java实现聊天,服务端与客户端代码(UDP)-狂神改

首先是文件结构:

 

 

 

 

最后run的是下面两个

代码用的狂神的,不过他写的有点小bug,比如传信息会出现一堆空格(recieve data那里长度不应该用data.lenth()而应该用packet.getLenth()),

以及你输入退出关键词后,会同时把两边都close掉,虽然好像也可以这样不过怪怪的,于是我分开了

在这里用/exit作为退出关键词。输入后,输入方直接exit(0),接收方此时会收到“对方已下线”的提醒,这时候也可以输入/exit退出。

ok接下来是代码:

 

1.TalkRecieve

package socket.chat;

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

import static java.lang.System.exit;

public class TalkRecieve implements Runnable{

    DatagramSocket socket = null;
    private int port;
    private String msgFrom;

    public TalkRecieve(int port,String msgFrom) {
        this.port = port;
        this.msgFrom = msgFrom;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException 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,packet.getLength());
                System.out.println(msgFrom+":"+receiveData);
                if(receiveData.equals("/exit")){
                    System.out.println("【系统】:对方已下线。使用/exit退出");
                    break;

                }




            }catch (IOException e){
                e.printStackTrace();

            }
        }
        socket.close();




    }
}

 

2.TalkSend

package socket.chat;

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

import static java.lang.System.exit;

public class TalkSend implements Runnable{
    DatagramSocket socket = null;
    BufferedReader reader = null;
    private int fromPort;
    private String toIP;
    private int toPort;

    public TalkSend(int fromPort, String toIP, int toPort) {
        this.fromPort = fromPort;
        this.toIP = toIP;
        this.toPort = toPort;
        try{
            socket = new DatagramSocket(fromPort);
            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();
                DatagramPacket packet = new DatagramPacket(datas,0,datas.length,new InetSocketAddress(this.toIP,this.toPort));

                socket.send(packet);
                if(data.equals("/exit")) {
                    break;
                }
            }catch(Exception e){
                e.printStackTrace();
            }

            }
        socket.close();
        exit(0);
        }
    }

 

3.TalkStudent(一方)

package socket.chat;
//学生从7777发出,发向对方的9999
//学生准备从8888接收老师的消息
//从哪里发出并不重要,重要的是发向哪里和接收在哪里
public class TalkStudent {
    public static void main(String[] args) {
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkRecieve(8888,"老师")).start();
    }
}

 

4.TalkTeacher(另一方)

基本一致,只是send的port和reiceve的prot换了

这里发送来源port是无所谓的(只要别填个会被占用的就行了)

package socket.chat;
//学生从7777发出,发向对方的9999
//学生准备从8888接收老师的消息
//从哪里发出并不重要,重要的是发向哪里和接收在哪里
public class TalkStudent {
    public static void main(String[] args) {
        new Thread(new TalkSend(7777,"localhost",9999)).start();
        new Thread(new TalkRecieve(8888,"老师")).start();
    }
}

 

posted @ 2022-03-30 15:35  Fordson  阅读(115)  评论(0)    收藏  举报