首页 > 其他分享 >TCP通信:群聊案例

TCP通信:群聊案例

时间:2023-06-08 18:33:54浏览次数:44  
标签:java socket TCP 案例 import msg 群聊 new Socket

 

 

package Karl.Demo.Test;

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.创建Sockrt对象,并同时请求与服务端程序连接
        Socket socket=new Socket("127.0.0.1",123456);
        //创造一个独立线程ClentReaerThread用来接受服务端随时都有可能发送来的数据
        //把socket客户端载入到新线程中,表示新线程是用客户端来接受数据,运行新线程
        new ClentReaerThread(socket).start();
        //得到字节输出流,用来发送给服务端
        OutputStream os=socket.getOutputStream();
        //把低级字节输出流包装成数据输出流
        DataOutputStream dos=new DataOutputStream(os);
        Scanner sc=new Scanner(System.in);
        System.out.println("----------客户端开启---------");
        while (true) {
            System.out.println("请输入:");
            String msg = sc.nextLine();

            //用户输入exit,就退出客户端
            if ("exit".equals(msg)) {
                System.out.println("-------退出-------");
                dos.close();
                socket.close();
                break;
            }


            //开始写数据出去
            dos.writeUTF(msg);
            dos.flush();
        }

    }
}
package Karl.Demo.Test;

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 List<Socket> onListSocket=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对象存入集合中
            onListSocket.add(socket);
            //获取IP地址
            System.out.println(socket.getRemoteSocketAddress()+"---------上线---------");
            //3.把这个客户端对应的socket通信管道,交给一个独立的线程负责处理
            new ServerRraderThread(socket).start();

        }

    }
}
package Karl.Demo.Test;

import java.io.*;
import java.net.Socket;

public class ServerRraderThread extends Thread{
    //定义一个socket
    private Socket socket;
    //定义一个有参构造器,把获取来的数据交给本接口的socket
    public ServerRraderThread(Socket socket){
        this.socket=socket;
    }
    //重写run方法
    @Override
    public void run() {
        try {
            //用本接口socket获取到的数据交给字节输入流is
            InputStream is=socket.getInputStream();
            //把低级字节输入流is包装成数据输入流dis
            DataInputStream dis=new DataInputStream(is);
            //把读取数据放入死循环
            while (true) {
                try {
                    //用数据输入流方法读取数据交给String定义的msg
                    String msg=dis.readUTF();
                    //打印
                    System.out.println(msg);
                    //把数据msg传给sendMsgToAll方法,用来实现发送给全部客户端
                    sendMsgToAll(msg);
                } catch (IOException e) {
                    //获取关闭服务器的IP
                    System.out.println(socket.getRemoteSocketAddress()+"-------离线-----");
                    //把下线的Socket对象从集合中删除
                    Server.onListSocket.remove(socket);
                    //释放资源
                    socket.close();
                    dis.close();
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //创建方法用来发送数据
    private void sendMsgToAll(String msg) throws IOException {
        //遍历所有在线Socket客户端
        for (Socket socket1 : Server.onListSocket) {
            //把遍历到的客户端管道赋值给低级字节输出流os
            OutputStream os=socket1.getOutputStream();
            //把低级字节输出流包装成数据输出流dos
            DataOutputStream dos=new DataOutputStream(os);
            //用数据输出流dos的方法write给遍历到的客户端管道发送数据
            dos.writeUTF(msg);
            //IO流方法刷新,防止数据发送不出去
            dos.flush();
        }
    }
}
package Karl.Demo.Test;

import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.Socket;

public class ClentReaerThread extends Thread{
    //定义一个socket
    private Socket socket;
    //定义一个有参构造器,把获取来的数据交给本接口的socket
    public ClentReaerThread(Socket socket) {
        this.socket = socket;
    }
    @Override
    public void run() {
        try {
            //用本接口socket获取到的数据交给字节输入流is
            InputStream is=socket.getInputStream();
            //把低级字节输入流is包装成数据输入流dis
            DataInputStream dis=new DataInputStream(is);
            //把读取数据放入死循环
            while (true) {
                try {
                    //用数据输入流方法读取数据交给String定义的msg
                    String msg=dis.readUTF();
                    //打印
                    System.out.println(msg);
                } catch (IOException e) {
                    //获取关闭服务器的IP
                    System.out.println(socket.getRemoteSocketAddress()+"-------本机离线-----");
                    //释放资源
                    socket.close();
                    dis.close();
                    break;
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

 

标签:java,socket,TCP,案例,import,msg,群聊,new,Socket
From: https://www.cnblogs.com/Karl-hut/p/17467352.html

相关文章

  • 一文读懂大厂面试的计算机网络面试题目(超详细整理)(TCP/IP,OSI,HTTP协议)
    对于大厂的面试来说,掌握基本的计算机网络知识十分必要,但是说实话就单单是博主觉得,看书去复习,是最好的“安眠药”,哈哈哈,所以具有针对性的去学习更加的有效果,所以直接看大厂的高频面试题,快速建立知识结构体系。以下的一些是博主通过博览众多平台的博客推文进行的汇总:1.计算机网络OS......
  • TCP粘包问题如何解决?
        在TCP的socket编程中,发送端和接收端都有成对的socket。发送端为了将多个发往接收端的包,更加高效的的发给接收端,于是采用了优化算法(Nagle算法),将多次间隔较小、数据量较小的数据,合并成一个数据量大的数据块,然后进行封包。那么这样一来,接收端就必须使用高效科学的拆包机......
  • Dockerfile构建案例
    #1.构建上下文和所需的文件[root@localhost~]#mkdirdockerfile-test[root@localhost~]#cddockerfile-test/[root@localhostdockerfile-test]#touchnginx.repo[root@localhostdockerfile-test]#touchDockerfile#2.编辑Dockerfile[root@localhostdockerfile-te......
  • 联邦学习算法介绍-FedAvg详细案例-Python代码获取
    联邦学习算法介绍-FedAvg详细案例-Python代码获取一、联邦学习系统框架二、联邦平均算法(FedAvg)三、联邦随梯度下降算法(FedSGD)四、差分隐私随联邦梯度下降算法(DP-FedSGD)五、差分隐私联邦平均算法(DP-FedAVG)六、FedAVG案例附代码1)案例背景2)参数设置3)结果展示4)代码详解七、完整......
  • 如何设置Windows操作系统TIME_WAIT状态的TCP连接快速回收时间?
    大规模Windows环境下,采用Nginx反向代理服务后,操作系统会产生较多TIME_WAIT的TCP(TransmissionControlProtocol)连接,操作系统默认TIME_WAIT的TCP连接回收时间是4分钟,TCP默认动态端口范围为开始端口49152,结束端口65535。这样会使回收TCP过慢导致系统吞吐量下降,甚至出现502访问失败问......
  • 原生AJAX案例浏览器报错:Cross origin requests are only supported for protocol
    报错信息如下:代码如下:<!DOCTYPEhtml><html><body><divid="demo"><h1>XMLHttpRequest对象</h1><buttontype="button"onclick="loadDoc()">更改内容</button></div><script>fu......
  • 查看tcp和udp端口是否开启
    telnet只能看tcproot@performance:~#telnet192.168.80.1049108Trying192.168.80.104...Connectedto192.168.80.104.Escapecharacteris'^]'.nc既可以看tcp也可以看udptcproot@performance:~#nc-vz192.168.80.1049108192.168.80.104:inversehostlookup......
  • 通信三要素:协议-TCP
          ......
  • 银行业数据中心性能测试案例——容量测试案例C
    1、案例背景在互联网技术快速发展的大背景下,基于“互联网+培训”的理念,利用信息通信技术以及互联网平台,将在线培训理念和互联网技术相融合,银行业全新的在线培训平台H系统应运而生。2、需求分析不同的群体关注的性能测试目标是不同的,所以,性能测试需求分析可以从业务需求角度和运行......
  • 软件测试工程师面试——假如要你测试 6 个月期限的 p2p 借款产品,你应该怎么设计案例,说
    分析:(回答思路:1站在用户的角度测试,用户怎么用,你就怎么测试。2 一个人扮演多种角色测试。 3多想出一些异常场景。) 1 借款产品投标结束日T+7时,满标和不满标的情况。 2 借款产品投标结束日T+7前,产品提前满标情况 3 产品成立后,每个月还款日前,检查系统有没有发出......