网络编程实现聊天功能(UDP协议)

来源:互联网 发布:python 中,math.sqrt 编辑:程序博客网 时间:2024/06/05 23:51

进行聊天室的开发需要先了解一下基础的知识。可以先看完我的上一篇文章后再来看这个小程序,会更加的有帮助。http://blog.csdn.net/qq_36748278/article/details/77803561

UDP协议的Socket通信

下面举个小例子来深入了解一下UDP协议的Socket通信
1、首先会有一个发送端和一个接收端
2、应该是接收端先启动,然后处于等待状态,等待发送端发送数据过来。

我们知道UDP协议是不建立连接,以数据包的形式进行发送。所以应该采用DatagramSocket类来处理。
需要使用到的类:
1、public class DatagramSocket:此类表示用来发送和接收数据报包的套接字。
      有构造方法:
      DatagramSocket() 构造数据报套接字并将其绑定到本地主机上任何可用的端口。
      DatagramSocket(int port) 创建数据报套接字并将其绑定到本地主机上的指定端口。
2、public final class DatagramPacket:此类表示数据报包。
      有构造方法:
      DatagramPacket(byte[] buf, int length, InetAddress address, int port)构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号。
3、public class InetAddress implements Serializable:此类表示互联网协议 (IP) 地址。
      没有构造方法。但是可以通过InetAddress 类中的静态方法,并且返回值同样是InetAddress 来实现。
      public static InetAddress getByName(String host):在给定主机名的情况下确定主机的 IP 地址。 主机名可以是机器名,也可以是其IP 地址的文本表示形式。如果提供字面值 IP 地址,则仅检查地址格式的有效性。 返回的类型是InetAddress ,因此等于说同样可以调用这个类中的方法。
      public String getHostAddress():返回 IP 地址字符串(以文本表现形式)。
      public String getHostName():获取此 IP 地址的主机名。

UDP协议的初版

UDP协议发送数据
1、创建发送端的发送对象
2、创建数据并把数据打包
3、调用Socket对象的发送方法发送数据包
4、释放资源
UDP协议接收数据
1、创建接收端Socket对象
2、创建一个数据包(接收容器)
3、调用Socket对象的接收方法接收数据
4、解析数据包,并显示在控制台
5、释放资源
下面贴出发送端的代码:

public class SendDemo {    public static void main(String[] args) throws IOException {        //1、创建发送端Socket对象        DatagramSocket ds = new DatagramSocket();        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));       //实现键盘输入        String line = null;        while((line=br.readLine()) != null){                                            //通过while实现多次输入发送            if("end".equals(line)){                                                     //当输入"end"即关闭连接                break;            }            //2、创建数据,并把数据打包。将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号。            byte[] bytes = line.getBytes();                                             //创建数据            InetAddress address = InetAddress.getByName("danni");                       //IP地址对象            DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, 10088);            //3、通过Socket对象的发送方法发送数据包            ds.send(dp);        }        //4、释放资源        ds.close();    }}

接收端的代码:

public class RecieveDemo {    public static void main(String[] args) throws IOException {        //1、DatagramSocket(int port):创建数据报套接字并将其绑定到本地主机上的指定端口。        DatagramSocket ds = new DatagramSocket(10088);        while(true){            //2、创建一个数据包,用来接收数据            byte[] bytes = new byte[1024];            DatagramPacket dp = new DatagramPacket(bytes, bytes.length);            //3、接收数据            ds.receive(dp);            //4、解析数据,显示出来            InetAddress address = dp.getAddress();            String ip = address.getHostAddress();                       //获取对方的ip            String s = new String(dp.getData(), 0, dp.getLength());            System.out.println(ip + ":" + s);        }        //接收端应该一直开着等着接收数据,不需要关闭        //ds.close();    }}

先运行接收端代码,然后在运行发送端代码。
然后在发送端进行发送。
这里写图片描述
接收端收到数据并显示出来。
这里写图片描述


但是这个代码也有不足之处,它的发送消息和接收消息实在两个窗口才能完成。我想要他们在一个窗口就可以完成需要进行改进。下面是我的改进版本。可以实现在一个窗口进行发送和接收数据。

UDP协议的改进版

通过多线程实现。实现在一个窗口发送和接收数据。
网络程序本质就是多线程、IO流、网络编程组成。
主要的代码如下:

public class ChatRoom {    public static void main(String[] args) throws SocketException {        DatagramSocket dsSend = new DatagramSocket();                     DatagramSocket dsRecieve = new DatagramSocket(12034);        SendThread st = new SendThread(dsSend);               //实例化发送消息类,把DatagramSocket对象实例作为参数               RecieveThread rt = new RecieveThread(dsRecieve);      //实例化接收消息类,把DatagramSocket对象实例作为参数               Thread t1 = new Thread(st);       //创建发送线程        Thread t2 = new Thread(rt);       //创建接受线程        t1.start();                       //启动发送线程        t2.start();                       //启动接收线程    }}

SendThread主要代码:

public class SendThread implements Runnable {    private DatagramSocket ds;    public SendThread(DatagramSocket ds) {        this.ds = ds;    }    @Override    public void run() {        try{            BufferedReader br = new BufferedReader(new InputStreamReader(System.in));            String line = null;            while((line=br.readLine()) != null){                if("end".equals(line)){                    break;                }                //创建数据,并把数据打包。将要发送的数据、其长度、远程主机的 IP 地址和远程主机的端口号。                byte[] bytes = line.getBytes();                     //创建数据                InetAddress address = InetAddress.getByName("danni");       //IP地址对象                DatagramPacket dp = new DatagramPacket(bytes, bytes.length, address, 12034);                //通过Socket对象的发送方法发送数据包                ds.send(dp);            }            //释放资源            ds.close();        }catch(IOException e){            e.printStackTrace();        }    }}

RecieveThread代码如下:

public class RecieveThread implements Runnable {    private DatagramSocket ds;    public RecieveThread(DatagramSocket ds) {        this.ds = ds;    }    @Override    public void run() {        try{            while(true){                byte[] bytes = new byte[1024];                DatagramPacket dp = new DatagramPacket(bytes, bytes.length);                ds.receive(dp);                // 获取对方的ip                InetAddress address = dp.getAddress();                String ip = address.getHostAddress();                String s = new String(dp.getData(), 0, dp.getLength());                System.out.println(ip + ":" + s);            }        }catch(IOException e){            e.printStackTrace();        }    }}

效果如下:
这里写图片描述

原创粉丝点击