{"id":21974121,"url":"https://github.com/javaobjects/demo522","last_synced_at":"2025-03-22T23:25:38.032Z","repository":{"id":105562352,"uuid":"197678500","full_name":"javaobjects/demo522","owner":"javaobjects","description":"Java高级应用编程—— 网络编程","archived":false,"fork":false,"pushed_at":"2019-08-01T08:03:32.000Z","size":892,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-01-28T03:17:17.006Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/javaobjects.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-07-19T01:13:46.000Z","updated_at":"2019-08-01T08:03:34.000Z","dependencies_parsed_at":"2023-08-23T22:34:45.401Z","dependency_job_id":null,"html_url":"https://github.com/javaobjects/demo522","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo522","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo522/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo522/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javaobjects%2Fdemo522/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/javaobjects","download_url":"https://codeload.github.com/javaobjects/demo522/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":245033727,"owners_count":20550320,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-29T15:38:44.686Z","updated_at":"2025-03-22T23:25:38.007Z","avatar_url":"https://github.com/javaobjects.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 155-Java-网络编程实现简单的群聊功能.md\n\n![](155-Images/1.png)\n\n```\npackage chat3.client;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.net.Socket;\n\n/**\n * \n* \u003cp\u003eTitle: MyClient_receivemess_thread\u003c/p\u003e  \n* \u003cp\u003e\n*\tDescription: \n*\t收信息的线程\n* \u003c/p\u003e \n* @author xianxian \n* @date 2019年7月19日\n */\npublic class MyClient_receivemess_thread implements Runnable {\n\n\tprivate Socket client;\n\t\n\tpublic MyClient_receivemess_thread(Socket client) {\n\t\tsuper();\n\t\tthis.client = client;\n\t}\n\t@Override\n\tpublic void run() {\n\t\ttry(\n\t\t\t\tBufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));\n\t\t\t\t){\n\t\t\twhile (true) {\n\t\t\t\tString message = br.readLine();\n\t\t\t\tSystem.out.println(message);\n\t\t\t}\n\t\t}catch(Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n```\n```\npackage chat3.client;\n\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.net.Socket;\nimport java.util.Scanner;\n\npublic class MyClient {\n\n\tpublic static void main(String[] args) {\n\n\t\t/**\n\t\t * 需求：至少两个线程，\n\t\t * 一 个发 信息\n\t\t * 一个收信息\n\t\t */\n\t\tSocket client = null;\n\t\t\n\t\ttry {\n\t\t\t//此处的127.0.0.1相当于localhost\n\t\t\tclient = new Socket(\"127.0.0.1\",20000);\n\t\t\t\n\t\t\t\n\t\t\t//记得开一个子线程，不停的收取服务端转发过来的信息\n\t\t\tnew Thread(new MyClient_receivemess_thread(client)).start();\n\t\t\t\n\t\t\t\n\t\t\t//希望能够群聊，我能发信息出去\n\t\t\ttry(\n\t\t\t\t\tPrintWriter pw = new PrintWriter(new OutputStreamWriter(client.getOutputStream()),true);\n\t\t\t\t\t\n\t\t\t\t\t){\n\t\t\t\twhile(true) {\n\t\t\t\t\t//控制台输入要发送的信息\n\t\t\t\t\tScanner s = new Scanner(System.in);\n\t\t\t\t\tString message = s.next();\n\t\t\t\t\tpw.println(message);\n\t\t\t\t}\n\t\t\t}catch(Exception e) {\n\t\t\t\te.printStackTrace();\n\t\t\t}\n\t\t}catch(Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n```\n```\npackage chat3.server;\n\nimport java.net.ServerSocket;\nimport java.net.Socket;\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\n\npublic class MyServer {\n\t/**\n\t * \n\t * \u003cp\u003eTitle: main\u003c/p\u003e  \n\t * \u003cp\u003e\n\t * \tDescription: \n\t * 需求分析：1. 服务端能够响应客户端的连接请求，不管多少个都可以响应\n\t * \t\t\t2.客户端发送过来的信息，服务端可以转发给其他客户端\n\t * \u003c/p\u003e  \n\t * @param args\n\t */\n\t\n\t//存放客户端套接字的集合,为什么给集合上锁，支持并发访问，确保数据安全\n\tpublic static List\u003cSocket\u003e socketList = Collections.synchronizedList(new ArrayList\u003c\u003e());\n\t\n\tpublic static void main(String[] args) {\n\t\t//开一个服务端\n\t\tServerSocket server = null;\n\t\t\n\t\ttry {\n\t\t\tserver = new ServerSocket(20000);\n\t\t\t\n\t\t\twhile(true) {\n\t\t\t\tSocket client = server.accept();\n\t\t\t\t//拿到客户端套接字后需要做两件事：\n\t\t\t\t//1.把这个套接字放入集合中\n\t\t\t\tsocketList.add(client);\n\t\t\t\t\n\t\t\t\t//2.开一个线程跟客户聊天，\n\t\t\t\t//其实不聊天，只是不停的接收客户端发\n\t\t\t\t//来的信息然后转发至其他客户端\n\t\t\t\tnew Thread(new MyServer_chat_thread(client)).start();\n\t\t\t}\n\t\t} catch (Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n```\n```\npackage chat3.server;\n\nimport java.io.BufferedReader;\nimport java.io.InputStreamReader;\nimport java.io.OutputStreamWriter;\nimport java.io.PrintWriter;\nimport java.net.Socket;\n\n/**\n * \n* \u003cp\u003eTitle: MyServer_chat_thread\u003c/p\u003e  \n* \u003cp\u003e\n*\tDescription: \n*\t服务端和客户端聊天的线程类\n*\t需求：一直不停地接收客户端发来的信息然后转发至其他客户端\n* \u003c/p\u003e \n* @author xianxian \n* @date 2019年7月19日\n */\npublic class MyServer_chat_thread implements Runnable {\n\n\tprivate Socket client;//能够接收客端发送的信息，必定持有该客户端套接字\n\t\n\tpublic MyServer_chat_thread(Socket socket) {\n\t\tthis.client = socket;//利用构造方法构造当前类的实例的同时，给套接字属性赋值\n\t}\n\t@Override\n\tpublic void run() {\n\t\t//一直不停地接收客户端发来的信息然后转发至其他客户端\n\t\ttry(\n\t\t\t\tBufferedReader br = new BufferedReader(new InputStreamReader(client.getInputStream()));\n\t\t\t\t\n\t\t\t\t){\n\t\t\tString message = null;\n\t\t\twhile(true) {\n\t\t\t\tmessage = br.readLine();//接收客户端发送的信息\n\t\t\t\t//转发\n\t\t\t\tfor(Socket socket:MyServer.socketList) {\n\t\t\t\t\t//如果是自己发的信息，不用转发回自己\n\t\t\t\t\tif(socket == client) {\n\t\t\t\t\t\n\t\t\t\t\t\tcontinue;\n\t\t\t\t\t}else {\n\t\t\t\t\t\t//拿到每个客户端的套接字做什么呢？获取每个客户端的输出流，给各自的客户端发送信息\n\t\t\t\t\t\t//后面的参数true表明启动自动刷新功能\n\t\t\t\t\t\tPrintWriter pw = new PrintWriter(new OutputStreamWriter(socket.getOutputStream()),true);\n\t\t\t\t\t\t\n\t\t\t\t\t\tpw.println(message);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}catch(Exception e) {\n\t\t\te.printStackTrace();\n\t\t}\n\t}\n}\n```\n群聊功能测试：先启动MyServer再启动MyClient启动两次表明开咯两客户端，群聊功能如下图所示\n\n![](155-Images/2.gif)\n\n\n**以上就是我关于 *Java网络编程实现简单的群聊功能*  知识点的整理与总结的全部内容,[另附源码](https://github.com/javaobjects/demo522)**\n\n==================================================================\n#### 分割线\n==================================================================\n\n**博主为咯学编程：父母不同意学编程，现已断绝关系;恋人不同意学编程，现已分手;亲戚不同意学编程，现已断绝来往;老板不同意学编程,现已失业三十年。。。。。。如果此博文有帮到你欢迎打赏，金额不限。。。**\n\n![](155-Images/pay.png)","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavaobjects%2Fdemo522","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjavaobjects%2Fdemo522","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavaobjects%2Fdemo522/lists"}