UDP network programming+IO+multithreading---->chat room

network programming

​ UDP network programming+IO+multithreading---->chat room

UDP is a non-connection protocol. The source and terminal do not establish a connection before transmitting data . When it wants to transmit, it simply grabs the data from the application and throws it on the network as quickly as possible. We often use the "ping" command to test whether the TCP/IP communication between two hosts is normal. In fact, the principle of the "ping" command is to send a UDP data packet to the other host, and then the other host confirms the receipt of the data packet. The information that arrives is fed back in time, then the network is connected.

Idea: UDP realizes one-way data transmission, that is, one sender and one receiver. Chatting needs to send messages in both directions. We can write two classes to implement sending and receiving messages respectively and let them implement the Runnable interface, so that the threads that send and receive messages are run at the same time while chatting.

Socket socket

Sender class

package SocketProgramming;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

//UDP消息发送不需要链接服务器

//发送端
public class TalkSend implements Runnable{
    
    

    //建立一个Socket
    DatagramSocket socket = null;
    //IO流
    BufferedReader reader = null;
    //发出端口和接收目标的接收端口
    private int fromPort;
    private int toPort;
    //接收目标IP
    private String toIP;

    public TalkSend(int fromPort, String toIP, int toPort) {
    
    
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;

        try {
    
    
            socket = new DatagramSocket(fromPort);
            //控制台读取文字 System.in
            reader = new BufferedReader(new InputStreamReader(System.in));
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
    
    
        while (true){
    
    
            try {
    
    
                //读入数据
                String data = reader.readLine();
                //转为字节流
                byte[] datas = data.getBytes();
                //数据包:数据,数据长度,发送给谁(IP加端口)
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,
                        new InetSocketAddress(this.toIP,this.toPort));
                //发送包
                socket.send(packet);
                //trim()去空格
                if (data.trim().equals("bye")){
    
    
                    break;
                }
            }catch (Exception e){
    
    
                e.printStackTrace();
            }
        }
        //程序结束记得先断开连接释放系统资源
        socket.close();
        try {
    
    
            reader.close();
        } catch (IOException e) {
    
    
            e.printStackTrace();
        }
    }
}

Receiver class

package SocketProgramming;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

//接收端
public class TalkReceive implements Runnable{
    
    
    //建立一个Socket
    DatagramSocket socket = null;
    //接收者的端口
    private int port;
    //标记发送者的名字
    private String msgFrom;

    public TalkReceive(int port,String msgFrom) {
    
    
        this.port = port;
        this.msgFrom = msgFrom;
        try {
    
    
            socket = new DatagramSocket(port);
        }catch (Exception e){
    
    
            e.printStackTrace();
        }
    }

    @Override
    public void run() {
    
    
        while (true){
    
    
            try {
    
    
                //准备接收数据包
                byte[] container = new byte[1024];
                DatagramPacket packet = new DatagramPacket(container, 0 ,container.length);
                socket.receive(packet);//阻塞式接收包裹
                //读取数据
                byte[] data = packet.getData();
                String receiveData = new String(data, 0 ,data.length);

                System.out.println(msgFrom + ":"+receiveData);
                if (receiveData.trim().equals("bye")){
    
    
                    break;
                }
            } catch (IOException e) {
    
    
                e.printStackTrace();
            }
        }
        //断开连接
        socket.close();
    }
}

Two test classes simulate two people chatting

package SocketProgramming;

//学生和老师通信,两者都是接收方和发送方,调用两个线程接收和发送
public class TestTalkStudent {
    
    
    public static void main(String[] args) {
    
    
        //开启两个线程
        new Thread(new TalkReceive(8888,"老师")).start();
        new Thread(new TalkSend(7777,"localhost",9999)).start();
    }
}
package SocketProgramming;

public class TestTalkTeacher {
    
    
    public static void main(String[] args) {
    
    
        //开启两个线程
        new Thread(new TalkReceive(9999,"学生")).start();
        new Thread(new TalkSend(5555,"localhost",8888)).start();
    }
}

operation result

In fact, it is similar to qq. Two people are online chatting at the same time, and one can receive offline messages when one is offline, and the bye program ends when two people are at the same time.

Insert picture description here

Why close()

When we create a new java stream object, not only an instance object of the corresponding class is created in the computer memory. Moreover, it also occupies corresponding system resources, such as file handles, ports, database connections, and so on. The instance object in the memory, when there is no reference to it, the java garbage collector will automatically reclaim it according to the corresponding strategy, but it cannot release the system resources. Therefore, we need to actively call the close() method to release the java stream object. After java7, you can use the try-with-resources statement to release the java stream object, thereby avoiding the cumbersome try-catch-finally statement, especially in the finally clause, the close() method will also throw an exception.

IO streaming requires intensive learning!

Guess you like

Origin blog.csdn.net/weixin_44529429/article/details/113208126