网络编程5

发布时间:2026/7/29 21:50:43
网络编程5 TCP通信-群聊Serverpackage TCP3; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.ServerSocket; import java.net.Socket; import java.util.ArrayList; import java.util.List; public class Server{ public static ListSocket OnlineSockets new ArrayList(); public static void main(String[] args) throws Exception{ System.out.println(...服务端启动成功...); //1.创建ServerSocket的对象同时为服务端注册端口 ServerSocket serverSocket new ServerSocket(8888); while (true) { //2.使用serverSocket对象调用一个accept方法等待客户端连接请求 Socket socket serverSocket.accept(); //添加在线Socket OnlineSockets.add(socket); //追踪客户端上限 System.out.println(有人上线了 socket.getRemoteSocketAddress()); //3.把这个客户端对应的socket通信管道交给一个独立的线程负责处理 new ServerReaderTread(socket).start(); } } }创建服务端及其端口后使用死循环与多个客户端链接然后再分配子进程去管理这个客户端发来的消息ServerReadTreadpackage TCP3; import java.io.*; import java.net.Socket; public class ServerReaderTread extends Thread { //线程变量 private Socket socket; //有参构造器 public ServerReaderTread(Socket socket){ this.socket socket; } public void run(){ //从socket通信管理中得到一个字节输入流 try { InputStream is socket.getInputStream(); DataInputStream dis new DataInputStream(is); while (true){ try { String msg dis.readUTF(); System.out.println(msg); //把这个消息发给全部客户端进行接收 sendMsgToAll(msg); } catch (IOException e) { System.out.println(有人下线了 socket.getRemoteSocketAddress()); //在在线Socket集合中删除对应端口 Server.OnlineSockets.remove(socket); dis.close(); socket.close(); break; } } } catch (Exception e) { throw new RuntimeException(e); } } private void sendMsgToAll(String msg) throws IOException { //发送给全部在线的socket管道接收 for (Socket onlineSocket : Server.OnlineSockets) { OutputStream os onlineSocket.getOutputStream(); DataOutputStream dos new DataOutputStream(os); dos.writeUTF(msg); dos.flush(); } } }客户端每与服务端连接就会生成这个对应的子进程来管理将输入字节流转换为数据流后将其打印跟踪客户端是否下线最后将消息转发给所有在线的socket管道Clientpackage TCP3; import java.io.DataOutputStream; import java.io.OutputStream; import java.net.Socket; import java.util.Scanner; public class Client{ public static void main(String[] args) throws Exception{ //1.创建Socket对象并同时请求与服务端的连接 Socket socket new Socket(127.0.0.1,8888); //创建一个独立的线程负责随机从socket中接收服务端发送过来的消息 new ClientReaderTread(socket).start(); //2.从socket通信管道中得到一个字节输出流用来发数据给服务端程序 OutputStream os socket.getOutputStream(); //3.把低级的字节输出流包装成数据输出流 DataOutputStream dos new DataOutputStream(os); Scanner sc new Scanner(System.in); while (true) { System.out.println(); String msg sc.nextLine(); //一旦用户输入了exit就退出客户端程序 if(exit.equals(msg)){ System.out.println(已成功退出); dos.close(); socket.close(); break; } //4.开始写数据出去了 dos.writeUTF(msg); dos.flush(); } } }创建客户端后创建对应的客户端子进程用来接收信息使用死循环不断将信息发送,ClientReaderTreadpackage TCP3; import java.io.DataInputStream; import java.io.IOException; import java.io.InputStream; import java.net.Socket; public class ClientReaderTread extends Thread { //线程变量 private Socket socket; //有参构造器 public ClientReaderTread(Socket socket){ this.socket socket; } public void run(){ try { InputStream is socket.getInputStream(); DataInputStream dis new DataInputStream(is); while (true){ try { String msg dis.readUTF(); System.out.println(msg); } catch (IOException e) { System.out.println(自己下线了 socket.getRemoteSocketAddress()); dis.close(); socket.close(); break; } } } catch (Exception e) { throw new RuntimeException(e); } } }也是从通信管道中获取这个信息输入流然后将其打印出来