• TCP实战:即时通信-端口转发


    1、即时通信是什么含义,要实现怎么样的设计?

    • 即时通信,是指一个客户端的消息发出去,其他客户端可以接收到
    • 即时通信需要进行端口转发的设计思想
    • 服务端需要把在线的Socket管道存储起来
    • 一旦收到一个消息要推送给其他管道

    服务端 

    1. package com.csdn.demo07_tcp5_sms;
    2. import java.io.*;
    3. import java.net.ServerSocket;
    4. import java.net.Socket;
    5. import java.util.ArrayList;
    6. import java.util.List;
    7. /**
    8. * 目标:实现 服务端 可以同时处理 多个客户端 的消息
    9. */
    10. public class ServerDemo2 {
    11. //定义一个静态的List集合存储当前全部在线的socket管道
    12. public static List allOnlineSockets = new ArrayList<>();
    13. public static void main(String[] args) {
    14. try {
    15. System.out.println("===服务端启动成功===");
    16. //1、注册端口
    17. ServerSocket serverSocket = new ServerSocket(7777);
    18. //a.定义一个死循环由主线程负责不断的接收客户端的Socket管道连接
    19. while (true) {
    20. //2、每接收到一个客户端的Socket管道,交给一个独立的子线程负责读取消息
    21. Socket socket = serverSocket.accept();
    22. //上线逻辑
    23. System.out.println(socket.getRemoteSocketAddress() + "上线了,来了老弟!!");
    24. allOnlineSockets.add(socket);//上线完成
    25. //3、开始创建独立线程处理socket
    26. new ServerReaderThread(socket).start();
    27. }
    28. } catch (IOException e) {
    29. throw new RuntimeException(e);
    30. }
    31. }
    32. }
    33. class ServerReaderThread extends Thread {
    34. private Socket socket;
    35. public ServerReaderThread(Socket socket) {
    36. this.socket = socket;
    37. }
    38. @Override
    39. public void run() {
    40. try {
    41. //3、从socket通信管道中得到一个字节输入流
    42. InputStream is = socket.getInputStream();
    43. //4、把字节输入流包装成缓冲字符输入流进行消息的接收
    44. BufferedReader br = new BufferedReader(new InputStreamReader(is));
    45. //5、按照行读取消息
    46. String msg;
    47. while ((msg = br.readLine()) != null) {
    48. System.out.println(socket.getRemoteSocketAddress() + "发来了:" + msg);
    49. //把这个消息进行端口转发给全部客户端socket管道
    50. sendMsgToAll(msg);
    51. }
    52. } catch (IOException e) {
    53. System.out.println(socket.getRemoteSocketAddress() + "下线了,下次再来哦,老弟!!");
    54. ServerDemo2.allOnlineSockets.remove(socket);
    55. }
    56. }
    57. private void sendMsgToAll(String msg) throws IOException {
    58. for (Socket socket : ServerDemo2.allOnlineSockets) {
    59. PrintStream ps = new PrintStream(socket.getOutputStream());
    60. ps.println(msg);
    61. ps.flush();
    62. }
    63. }
    64. }

     客户端

    1. package com.csdn.demo07_tcp5_sms;
    2. import java.io.*;
    3. import java.net.Socket;
    4. import java.util.Scanner;
    5. /**
    6. * 目标:完成 Socket 客户端开发,实现 多发 和 多收
    7. */
    8. public class ClientDemo1 {
    9. public static void main(String[] args) {
    10. try{
    11. System.out.println("===客户端启动===");
    12. //1、创建Socket通信管道请求有服务端的连接
    13. Socket socket = new Socket("127.0.0.1", 7777);
    14. //创建一个独立的线程专门负责这个客户端的读消息(服务端随时可能转发消息过来!)
    15. new ClientReaderThread(socket).start();
    16. //2、从socket通信管道中得到一个字节输出流 负责发送数据
    17. OutputStream os = socket.getOutputStream();
    18. //3、把低级的字节流包装成打印流
    19. PrintStream ps = new PrintStream(os);
    20. Scanner sc = new Scanner(System.in);
    21. while (true) {
    22. System.out.println("请说:");
    23. String msg = sc.nextLine();
    24. //4、发送消息
    25. ps.println(msg);
    26. ps.flush();
    27. }
    28. } catch (IOException e) {
    29. throw new RuntimeException(e);
    30. }
    31. }
    32. }
    33. class ClientReaderThread extends Thread {
    34. private Socket socket;
    35. public ClientReaderThread(Socket socket) {
    36. this.socket = socket;
    37. }
    38. @Override
    39. public void run() {
    40. try {
    41. //3、字节输入流
    42. InputStream is = socket.getInputStream();
    43. //4、把低级的字节输入流包装成高级的缓冲字符输入流
    44. BufferedReader br = new BufferedReader(new InputStreamReader(is));
    45. //5、按照行读取
    46. String line;
    47. while ((line = br.readLine()) != null) {
    48. System.out.println("收到消息" + line);
    49. }
    50. } catch (IOException e) {
    51. System.out.println("服务器把你踢出去了~~~");
    52. }
    53. }
    54. }
  • 相关阅读:
    Verilog中关于reg [3:0] a [7:0] 和 reg [3:0] [7:0] a的区别
    分享68个毕业答辩PPT,总有一款适合您
    【List篇】使用Arrays.asList生成的List集合,操作add方法报错
    用R语言实现环境流行病学中的时间序列回归:以2002-2006年伦敦数据集为例
    基于单片机的胎压监测系统的设计
    position: sticky;实现顶部悬停,吸顶效果
    宝宝照片保存大法!一键制作照片书
    【2018统考真题】给定一个含n(n≥1)个整数的数组,请设计一个在时间上尽可能高 效的算法,找出数组中未出现的最小正整数。
    Python \r \n换行符的研究
    【计算机毕业设计】企业员工岗前培训管理系统
  • 原文地址:https://blog.csdn.net/m0_65152767/article/details/133952225