基于UDP通信的聊天程序JAVA程序设计 课程设计报告.doc

上传人:精*** 文档编号:850624 上传时间:2023-09-16 格式:DOC 页数:18 大小:470KB
下载 相关 举报
基于UDP通信的聊天程序JAVA程序设计 课程设计报告.doc_第1页
第1页 / 共18页
基于UDP通信的聊天程序JAVA程序设计 课程设计报告.doc_第2页
第2页 / 共18页
基于UDP通信的聊天程序JAVA程序设计 课程设计报告.doc_第3页
第3页 / 共18页
基于UDP通信的聊天程序JAVA程序设计 课程设计报告.doc_第4页
第4页 / 共18页
基于UDP通信的聊天程序JAVA程序设计 课程设计报告.doc_第5页
第5页 / 共18页
点击查看更多>>
资源描述

1、 基于UDP通信的聊天程序1 协议介绍和使用说明1.1 协议内容本课程设计主要是基于UDP的并用Java实现的简单的聊天程序。UDP 用户数据报是在运输层的端到端抽象的逻辑信道中传送的。UDP 在传送数据之前不需要先建立连接。对方的运输层在收到 UDP 报文后,不需要给出任何确认。虽然 UDP 不提供可靠交付,但在某些情况下 UDP 是一种最有效的工作方式。虽然UDP 用户数据报只能提供不可靠的交付,但 UDP 在某些方面有其特殊的优点,它有即时通信的功能。比如说,使用聊天程序聊天的时候,省去的了跟对方通信的时候的链接的麻烦,直接进行通信。UDP 只在 IP 的数据报服务之上增加了很少一点的功

2、能,即端口的功能和差错检测的功能。UDP 使用尽最大努力交付,即不保证可靠交付,同时也不使用拥塞控制。UDP 是面向报文的。UDP 没有拥塞控制,很适合多媒体通信的要求。UDP 支持一对一、一对多、多对一和多对多的交互通信。发送方 UDP 对应用程序交下来的报文,在添加首部后就向下交付 IP 层。UDP 对应用层交下来的报文,既不合并,也不拆分,而是保留这些报文的边界。应用层交给 UDP 多长的报文,UDP 就照样发送,即一次发送一个报文。接收方 UDP 对 IP 层交上来的 UDP 用户数据报,在去除首部后就原封不动地交付上层的应用进程,一次交付一个完整的报文。1.2 关键技术1.2.1 服

3、务器端Socket的实现Socket又称作套接字,它是使用标准Unix文件描述符(filedescriptor)和其它程序通讯的方式。使用send()和recv()让你更好的控制数据传输。在Java 网络编程中,socket相当于应用程序的港口码头;在计算机网络中,套接字由ip地址和端口号组成,为进程之间通信提供地址。两个主机进行通信实际上就是两个主机中的应用进程互相通信,应用进程之间的通信又称为端到端的通信。为应用进程之间的通信提供运输服务的是运输层的运输协议,运输层需要有两种不同的运输协议,即面向连接的TCP和无连接的UDP。 在Java中,用于实现基于UDP的聊天程序,使用两个重要的类(

4、DatagramSocket类和DatagramPacket类)。DatagramSocket类表示用来发送和接收数据报包的套接字。数据报套接字是包投递服务的发送或接收点。每个在数据报套接字上发送或接收的包都是单独编址和路由的。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。 在DatagramSocket上总是启用UDP广播发送。为了接收广播包,应该将 DatagramSocket绑定到通配符地址。在某些实现中,将DatagramSocket绑定到一个更加具体的地址时广播包也可以被接收。atagramPacket类表示数据报包。 数据报包用来实现无连接包投递服务

5、。每条报文仅根据该包中包含的信息从一台机器路由到另一台机器。从一台机器发送到另一台机器的多个包可能选择不同的路由,也可能按不同的顺序到达。不对包投递做出保证。服务程序工作在服务器的某个端口上,一旦启动服务,它将在这个端口上监听,等待客户程序发来请求,当有客户连接到该端口,accept()方法就返回一个Socket对象,可以用该对象获得一个输入输出流。服务器的套接字用服务器套接字类(ServerSocket)来建立。具体实现如下:(1)建立一个服务者,端口为5000。(2)服务者永远等待,一旦客户送来正确的请求,连接至该端口,accept()方法就返回一个Socket对象。(3)用返回的Sock

6、et对象创建数据输入流类的实例in。用返回的Socket对象创建数据输出流的实例out。以上实例in和out是服务者用于从客户接受输入信息和向客户程序发送信息所用。此外,还需要用方法readline()和println()读取或输出一行数据。(4)soc.close()关闭Socket。1.2.2 通信的建立在客户端建立Socket对象,并进行异常处理,主机名和端口号与连接的服务器名和提供该服务的服务程序的监听端口必须一致。建立连接后用Socket类提供的getInputStream()和getOutputStream()方法取得输入输出流。在服务器端,获得的输入流是客户端的输出流,而Sock

7、et获得的输出流是发向客户端的输入流,在客户端也是这样。获得socket的输入输出流之后,为了便于读写操作,需要在这两个流对象基础上建立易于操作的数据流DateInputStream, DataOutputStream。然后对输入输出流进行读写操作。在通信结束时关闭socket,以断开连接,释放资源。先关闭对应的输入输出流,再关闭socket本身。1.2.2 数据库的建立mySQL数据库:2 程序设计2.1系统结构本系统采用一个服务器端和多个客户端的聊天方式来实现。结构图如下所示:图2.1服务器-客户端结构图2.2主程序设计2.2.1 服务器端程序 服务器与客户间通过套接口Socket连接。在

8、java中使用套接口相当简单,Java API为处理套接口的通信提供了一个类.Socket.,使得编写网络应用程序相对容易服务器采用多线程以满足多用户的请求,程序用vector向量数组存储连接客户变量,通过创建一个ServerSocket对象来监听来自客户的连接请求,默认端口为2012,然后无限循环调用accept()方法接受客户程序的连接。2.2.2 客户端程序 图2.2主程序流程图2.3 各模块设计2.3.1客户端向服务器发送消息 服务器与客户都通过DatagramSocket 以任意端口发送,DatagramPacket以2012端口来接收信息,信息从文本框输输入,一旦收到客户方的连接请

9、求,服务器accept()方法返回一个新建的Socket对象。客户端然后向服务器发送消息, 2.3.2客户端之间发送消息 客户间发送信息通过UDP来实现,用户登录时通过类DatagramPacket和DatagramSocket创建UDP包括其本地接受端口以及发送端口,默认端口为2012,通过取得的好友的IP地址来向好友发送消息(send(DatagramPacket)和接受消息(receive(DatagramPacket)。 2.4 界面设计2.4.1 界面设计的方法在Frame布局容器中,添加一个显示聊天的文本框(在上面),在加入Panel面板,Panel面板中包括三个TextField

10、单行文本框。 图2.3界面实现功能图2.4.2 界面的功能 界面中的组件有三个输入框,一个文本框,两个按钮。输入框要输入服务器的、用户名和要发送的聊天内容。文本框显示所以聊天人已经发送的聊天内容。按钮有连接按钮和发送按钮。服务器端只显示连接的建立、用户进入和退出、连接释放。2.5 实现代码实现通信的代码:package com.lcw.udp;import java.awt.Font;import java.awt.event.*;import java.io.BufferedWriter;import java.io.File;import java.io.FileWriter;import

11、 java.io.IOException;import .*;import javax.swing.*;public class UDPNetChat extends JFrame implements Runnableprivate static final long serialVersionUID = 1L;JLabel lab,lab1,lab2;JTextField tx,tx1,tx2;JButton but,but1,but2;JTextArea txa;public UDPNetChat()this.setLayout(null);/=lab=new JLabel(本机IP);

12、lab.setBounds(10,0,60,30);this.add(lab);tx=new JTextField(,20);tx.setBounds(75, 0, 200, 30);String adStr;try InetAddress addr=InetAddress.getLocalHost();int index=addr.toString().indexOf(/);adStr=addr.toString().substring(index+1);tx.setText(adStr); catch (UnknownHostException e) e.printStackTrace()

13、;this.add(tx);lab1=new JLabel(对方IP);lab1.setBounds(10, 30, 60, 30);this.add(lab1);lab2=new JLabel(发言:);lab2.setBounds(10, 70, 60, 30);this.add(lab2);tx1=new JTextField(,20);tx1.setBounds(75, 30, 200, 30);/tx1.setText(172.16.92.79);this.add(tx1);tx2=new JTextField();tx2.setBounds(75, 70, 300, 30);thi

14、s.add(tx2);but=new JButton(发送);but.setBounds(380, 70, 80, 30);but.setMnemonic(KeyEvent.VK_ENTER);but.addMouseListener(new myMouseListener();this.add(but);txa=new JTextArea();Font font = new Font(宋体, Font.PLAIN, 14);txa.setFont(font);txa.setBounds(15, 110, 450, 300);this.add(txa);but1=new JButton(保存聊

15、天记录);but1.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e) try String fileName = JOptionPane.showInputDialog(输入保存的文件名及所在路径);File file = new File(fileName);BufferedWriter bw = new BufferedWriter(new FileWriter(file);bw.write(txa.getText().toString();bw.close(); catch (

16、Exception ce) ce.printStackTrace(););but1.setBounds(30,430,150,30);but2=new JButton(退出聊天);but2.setBounds(200, 430, 150, 30);/退出聊天but2.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e) dispose(););this.add(but1);this.add(but2);/=this.setTitle(基于UDP的网络聊天程序);this.setBound

17、s(100, 100, 480, 550);this.setVisible(true);public void run() /接收数据while(true)/持续接收本地端的信息byte buf=new byte100;/预期最多可收100个bytetryDatagramSocket DS=new DatagramSocket(2012);/用2222 port 收DatagramPacket DP=new DatagramPacket(buf,buf.length);/将数据收到buf数组DS.receive(DP);tx1.setText(DP.getAddress().getHostAd

18、dress();txa.append(来自+DP.getAddress().getHostAddress()+:+DP.getPort()+new String(buf).trim()+n); /此处用new String(DP.getData().trim()也一样DS.close();Thread.sleep(200);catch(InterruptedException e)catch(SocketException e)catch(IOException e)class myMouseListener extends MouseAdapter/送数据public void mouseC

19、licked(MouseEvent e)/每次Click按钮就发送信息到目的端主机String msg=tx2.getText().trim();String ipStr=tx1.getText().trim();tryDatagramSocket DS=new DatagramSocket();/以任一目前可用的port送DatagramPacket DP=new DatagramPacket(msg.getBytes(),msg.getBytes().length,InetAddress.getByName(ipStr),2012);/送到远程的2012 portDS.send(DP);/

20、送出数据包txa.append(我说:+msg.trim()+n);/给自己看的记录DS.close();catch(SocketException e1)catch(IOException e1)客户端注册代码:package com.lcw.udp;import java.awt.*;import java.awt.event.*;import java.sql.*;import javax.swing.*;public class Register extends JFrame /* * param args */public static void main(String args)

21、Register frame=new Register();frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);JTextField tx1;JPasswordField psd1,psd2;public Register()this.setSize(300,150);this.setTitle(新用户注册);Container c=getContentPane();JPanel panel=new JPanel();panel.setLayout(new GridLayout(3,2);JLa

22、bel lab1,lab2,lab3;lab1=new JLabel(账号);lab2=new JLabel(密码);lab3=new JLabel(确认密码);tx1=new JTextField();psd1=new JPasswordField();psd2=new JPasswordField();panel.add(lab1);panel.add(tx1);panel.add(lab2);panel.add(psd1);panel.add(lab3);panel.add(psd2);c.add(panel,BorderLayout.CENTER);JPanel pan=new JPa

23、nel();JButton but1,but2,but3;but1=new JButton(注册);but2=new JButton(重置);but3=new JButton(直接登陆);/but1按钮事件处理but1.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e) String ID=tx1.getText().trim().toString();SuppressWarnings(deprecation)String pasd1=psd1.getText().toString()

24、;SuppressWarnings(deprecation)String pasd2=psd2.getText().toString();if(pasd1.equalsIgnoreCase(pasd2)tryClass.forName(com.mysql.jdbc.Driver);String url=jdbc:mysql:/localhost:3306/user;Connection conn=DriverManager.getConnection(url,root,root);Statement stmt=conn.createStatement();String sql=insert i

25、nto t_user values(+ID+,+pasd1+);ResultSet rs=stmt.executeQuery(select *from t_user);/*若譔账号已存在,则需要重新注册*/while(rs.next()if(rs.getString(ID).equals(ID)JOptionPane.showMessageDialog(null, 该账号已被注册,请重新注册!);elseint num=stmt.executeUpdate(sql);if(num0)JOptionPane.showMessageDialog(null, 恭喜您注册成功!);stmt.close

26、();conn.close();catch(Exception ce)ce.printStackTrace(););/but2按钮事件处理but2.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e) tx1.setText();psd1.setText();psd2.setText(););/but3按钮事件处理but3.addActionListener(new ActionListener()public void actionPerformed(ActionEvent e) Lo

27、gin log=new Login();dispose(););pan.add(but1);pan.add(but2);pan.add(but3);c.add(pan,BorderLayout.SOUTH);客户端登录代码:package com.lcw.udp;import java.awt.*;import java.awt.event.*;import javax.swing.*;import java.sql.*;public class Login extends JFrame/* * param args */JTextField tx1;JPasswordField psd1;p

28、ublic Login()this.setVisible(true);this.setSize(300,150);this.setTitle(用户登陆);Container c=getContentPane();JPanel panel=new JPanel();panel.setSize(300,80);panel.setLayout(new GridLayout(2,2);JLabel lab1,lab2;lab1=new JLabel(账号);lab2=new JLabel(密码);tx1=new JTextField();psd1=new JPasswordField();panel.

29、add(lab1);panel.add(tx1);panel.add(lab2);panel.add(psd1);c.add(panel,BorderLayout.CENTER);JPanel pan=new JPanel();JButton but1,but2;but1=new JButton(登陆);but2=new JButton(重置);/but1按钮事件处理but1.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) String ID = tx1.getText().tr

30、im().toString();SuppressWarnings(deprecation)String pasd1 = psd1.getText().toString();String driver = com.mysql.jdbc.Driver;String url = jdbc:mysql:/localhost:3306/user;try Class.forName(driver);Connection conn = DriverManager.getConnection(url, root,root);Statement stmt = conn.createStatement();Res

31、ultSet rs=stmt.executeQuery(select *from t_user);while(rs.next()if(rs.getString(ID).equals(ID)&rs.getString(pwd).equalsIgnoreCase(pasd1)UDPNetChat Form1 = new UDPNetChat();Thread threadObj = new Thread(Form1);threadObj.start();/ 启动接收消息的线程dispose();/*elseJOptionPane.showMessageDialog(null, 用户名或密码错误!)

32、;*/ catch (Exception ce) ce.printStackTrace(););/but2按钮事件处理but2.addActionListener(new ActionListener() public void actionPerformed(ActionEvent e) tx1.setText();psd1.setText(););pan.add(but1);pan.add(but2);c.add(pan,BorderLayout.SOUTH);2.6 程序调试及运行结果2.6.1 调试前的准备 安装jdk1.6.0并在计算机的环境变量中配置好java环境。使用的实验环境是

33、Windows XP,Eclipse 6.0,。使用2台主机进行通信,一台作为服务器,一台作为客户端。2.6.2 程序调试过程 启动eclipse首先在一台主机上运行服务器端程序,再在另外一台机器上运行客户端程序。然后进入到用户的图形用户界面,输入客户端的IP,进行连接,如果连接成功,则客户端就可以通过与服务器端进行通信,然后服务器转发通信,实现了两个客户端之间的聊天功能。2.6.3 程序运行结果该结果是在同一机器上运行结果:2.6.4 出错分析 在主机2的聊天窗口中第二行出现乱码,经检查是由于中文编码出现问题,而英文字符可以正确传输。在接受端的字符串的编码方法强制转换 msg=new Str

34、ing(Min.readLine().getBytes(ISO8859-1),GBK); 问题因此解决。3. 课设体会这次课设我们是两个人一起完成的,在设计过程中,由于我们对java知识的掌握不够,因此参考了很多课外的相关书籍,并且在很多同学的帮忙下共同完成的。通过实践让我们进一步掌握了网络和Java的结合,实现了网络编程。充分了解了基于UDP编程和功能模块化的优越性,这样便于维护和修改,并且很容易找到它有可能出现的错误和漏洞。当编译没有错误的时候,进行执行时,往往开始几次都不能达到自己的理想效果,这个时候的修改工作往往更加复杂,尤其是这个程序,整个程序大体上由几个类来控制,但是其实里面的类与

35、类相互之间的联系很多,类与类相互之间相互交织在一起,在设计的时候我就考虑了把实现一些功能类似的按钮的事件响应放到一起,这样在编译出错时就能很容易的修改错误,看起来也清晰明了,所以功能模块化对程序的阅读、调试、修改起了很重要的作用。但是这个程序从整体上的设计就导致了程序本身很难把各个功能模块化,这也是程序的一个BUG,如果改进的化要从开始设计的时候几个大类要重新规划。在设计程序的时候还要考虑到用户的非法操作而可能引起的系统错误和数据丢失,该程序在这方面做的不好,编程过程中没有充分考虑了各种可能出错的情况,纠错功能并不完善。改进的时候要把纠错功能充分的考虑进去。其实编写程序不仅仅让我们学到和更进一

36、步的理解了语言算法的结构和思想,还进一步培养了我们缜密的思维,考虑问题更加周到。总之,要想学好更好,我们仍需培养更好的默契和付出更多的努力。参考文献1.James F.Kurose, Keith W.Ross, 陈鸣译, 计算机网络自顶向下方法(第四版), 机械工业出版社, 2009.1 2.Larry L. Peterson;Bruce S. Davie, 薛静锋等译, 计算机网络系统方法(第四版), 机械工业出版社, 2009.2 3.William Stallings, Computer Networking with Internet Protocols and Technology, Prentis Hall,20034.计算机网络互联网协议与技术(英文版), 电子工业出版社, 2006.8 5.Shivendra S.Panwar, etc, 陈涓译, TCPIP基础教程,人民邮电出版社, 2006.12 6.吴功宜. 计算机网络. 21世纪大学本科计算机专业系列教材. 清华大学出版社. 2003.8 7 Paul Hyde , java线程编程,人民邮电出版社.2006.818

展开阅读全文
相关资源
相关搜索
资源标签

当前位置:首页 > 技术资料 > 课程设计

版权声明:以上文章中所选用的图片及文字来源于网络以及用户投稿,由于未联系到知识产权人或未发现有关知识产权的登记,如有知识产权人并不愿意我们使用,如有侵权请立即联系:2622162128@qq.com ,我们立即下架或删除。

Copyright© 2022-2024 www.wodocx.com ,All Rights Reserved |陕ICP备19002583号-1 

陕公网安备 61072602000132号     违法和不良信息举报:0916-4228922