先编写最简答的服务器

思路

  1. 1编写一个实现Runnable接口的静态内部类 ServerC,便于区分每个客户端
  2. 1.1 获取客户端数据函数 public String remsg()
  3. 1.2 转发消息给所有客户端(自己除外) public void allsend(String data)
  4. 1.3 释放资源 public void release()
  5. 1.4编写接口重写方法 public void run(),调用收消息和发消息方法。
  6.  
  7. 2server主函数监听客户端的请求
  8. 每次的客户端请求都将对应的 ServerC 保存到一个集合当中
  9. 最后开启一个线程单独对应
  1. package chat;
  2.  
  3. import java.io.DataInputStream;
  4. import java.io.DataOutputStream;
  5. import java.io.IOException;
  6. import java.net.ServerSocket;
  7. import java.net.Socket;
  8. import java.util.concurrent.CopyOnWriteArrayList;
  9.  
  10. public class ServerChat {
  11. private static CopyOnWriteArrayList<ServerC> all = new CopyOnWriteArrayList<>();
  12.  
  13. public static void main(String[] args) throws IOException {
  14. System.out.println("##################Server##############");
  15. ServerSocket server = new ServerSocket(8888);
  16. while (true){
  17. Socket socket = server.accept();
  18. System.out.println("进入");
  19. ServerC serverC = new ServerC(socket);
  20. all.add(serverC);
  21. //使用多线程分离各个客户端
  22. new Thread(serverC).start();
  23. }
  24. }
  25.  
  26. static class ServerC implements Runnable{
  27. private Socket socket;
  28. private DataOutputStream dos;
  29. private DataInputStream dis;
  30.  
  31. public ServerC(Socket socket) {
  32. this.socket = socket;
  33. try {
  34. dis = new DataInputStream(socket.getInputStream());
  35. dos = new DataOutputStream(socket.getOutputStream());
  36. } catch (IOException e) {
  37. e.printStackTrace();
  38. release();
  39. }
  40. }
  41.  
  42. /**
  43. * 获取客户端data
  44. * @return
  45. */
  46. public String remsg(){
  47. //接受消息
  48. String data = null;
  49. try {
  50. data = dis.readUTF();
  51. } catch (IOException e) {
  52. e.printStackTrace();
  53. }
  54. return data;
  55.  
  56. }
  57. //消息转发给所有人函数
  58. public void transaction(String data){
  59. try{
  60. dos.writeUTF(data);
  61. dos.flush();
  62. }catch (Exception e){
  63. release();
  64. }
  65. }
  66.  
  67. //群发给客户端
  68. public void allsend(String data) {
  69. for (ServerC serverC : all) {
  70. if (this == serverC) {
  71. continue;
  72. } else {
  73. serverC.transaction(data);
  74. }
  75.  
  76. }
  77. }
  78.  
  79. //释放资源函数
  80. public void release(){
  81. try {
  82. dos.close();
  83. dis.close();
  84. socket.close();
  85. } catch (IOException e) {
  86. e.printStackTrace();
  87. }
  88.  
  89. }
  90.  
  91. @Override
  92. public void run() {
  93. String data = remsg();
  94. allsend(data);
  95. }
  96. }
  97.  
  98. }

编写客户端的收消息类:

  1. package chat;
  2.  
  3. import java.io.DataInputStream;
  4. import java.io.IOException;
  5. import java.net.Socket;
  6.  
  7. public class ClientResevice implements Runnable{
  8. private Socket socket;
  9. private DataInputStream dis;
  10.  
  11. public ClientResevice(Socket socket) {
  12. this.socket = socket;
  13. try {
  14. this.dis = new DataInputStream(socket.getInputStream());
  15. } catch (IOException e) {
  16. e.printStackTrace();
  17. release();
  18. }
  19. }
  20.  
  21. @Override
  22. public void run() {
  23. while (true){
  24. //接受消息
  25. String msg = receive();
  26. if(!msg.isEmpty()){
  27. System.out.println(msg);
  28. }
  29. }
  30. }
  31.  
  32. /**
  33. * 接受消息函数
  34. * @return返回消息
  35. */
  36. public String receive(){
  37. String msg = null;
  38. try {
  39. msg = dis.readUTF();
  40. } catch (IOException e) {
  41. e.printStackTrace();
  42. release();
  43. }
  44. return msg;
  45. }
  46.  
  47. //释放资源函数
  48. public void release(){
  49. try {
  50. dis.close();
  51. socket.close();
  52. } catch (IOException e) {
  53. e.printStackTrace();
  54. }
  55. }
  56. }

客户端发消息类:

  1. package chat;
  2.  
  3. import java.io.BufferedReader;
  4. import java.io.DataOutputStream;
  5. import java.io.IOException;
  6. import java.io.InputStreamReader;
  7. import java.net.Socket;
  8.  
  9. /**
  10. * 创建发送消息线程类,发送和接受分开
  11. */
  12. public class ClientSend implements Runnable{
  13. private BufferedReader console;
  14. private DataOutputStream dos;
  15. private Socket socket;
  16.  
  17. /**
  18. * 建立发送消息线程类的构造函数
  19. * @param socket
  20. */
  21. public ClientSend( Socket socket){
  22. this.socket = socket;
  23. this.console = new BufferedReader(new InputStreamReader(System.in));
  24. try {
  25. this.dos = new DataOutputStream(socket.getOutputStream());
  26. } catch (IOException e) {
  27. e.printStackTrace();
  28. this.release();
  29. }
  30. }
  31.  
  32. /**
  33. * 实现Runnable里面的run方法
  34. */
  35. @Override
  36. public void run() {
  37. while (true){
  38. send();
  39. }
  40. }
  41.  
  42. /**
  43. *获取命令函输入函数
  44. * @return
  45. */
  46. public String conin(){
  47. String msg = null;
  48. try {
  49. msg = console.readLine();
  50. } catch (IOException e) {
  51. e.printStackTrace();
  52. }
  53. return msg;
  54. }
  55.  
  56. /**
  57. * 发送函数
  58. */
  59. public void send(){
  60. String msg = conin();
  61. if(!msg.isEmpty()){
  62. try {
  63. dos.writeUTF(msg);
  64. dos.flush();
  65. } catch (IOException e) {
  66. e.printStackTrace();
  67. }
  68. }
  69. }
  70.  
  71. //释放资源函数
  72. public void release(){
  73. try {
  74. dos.close();
  75. socket.close();
  76. } catch (IOException e) {
  77. e.printStackTrace();
  78. }
  79. }
  80. }

客户端代码,主要怎么使用发收消息类:

  1. package chat;
  2.  
  3. import java.io.*;
  4. import java.net.Socket;
  5.  
  6. public class FirstClient {
  7.  
  8. public static void main(String[] args) throws IOException {
  9. System.out.println("##############client################");
  10. Socket socket = new Socket("127.0.0.1",8888);
  11. // 启动发送消息线程
  12. new Thread(new ClientSend(socket)).start();
  13. // 启动接受线程
  14. new Thread(new ClientResevice(socket)).start();
  15. }
  16. }

java-网络通信--socket实现多人聊天(基于命令行)的更多相关文章

  1. java swing+socket实现多人聊天程序

    swing+socket实现多人聊天程序 1.准备工作 先看效果: 客户端项目结构图: 服务端项目结构图: 2.运行原理 服务端 先开一个线程serverListerner,线程中开启一个Server ...

  2. Java使用socket实现两人聊天对话

    import java.io.*; import java.net.ServerSocket; import java.net.Socket; import java.util.Scanner; /* ...

  3. 如何创建一个基于命令行工具的跨平台的 NuGet 工具包

    命令行可是跨进程通信的一种非常方便的手段呢,只需启动一个进程传入一些参数即可完成一些很复杂的任务.NuGet 为我们提供了一种自动导入 .props 和 .targets 的方法,同时还是一个 .NE ...

  4. Linux下基于命令行的抓包方法

    大家可能都已经对著名的抓包工具Ethereal比较熟悉了,这里再介绍一种基于命令行的抓包工具tcpdump. 举例:抓本机1813端口上的数据,并将抓包结果保存在test.cap文件中 然后在本地可以 ...

  5. POP3:基于命令行的电子邮件(EMail)在线查看和批量下载工具

    使用该工具可以在不安装outlook和foxmail等邮件客户端的情况下快速下载指定邮箱的邮件,并将下载的邮件以eml格式进行保存. 附: 查看eml格式的邮件可使用 EmlReader 工具,该工具 ...

  6. java socket之多人聊天室Demo

    一.功能介绍 该功能实现了一个类似QQ的最简单多人聊天室,如下图所示. 二.目录结构 三.服务端 1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程: pa ...

  7. 基于Socket实现多人聊天室

    当前支持: 1.仅文字 2.加入聊天室提醒 3.退出聊天室提醒 可能出现的BUG: 1.可能出现客户端发送信息后不能及时推送,需要下一个客户端发送信息后一起推送 服务端代码: 1 package co ...

  8. 多线程+socket实现多人聊天室

    最近在学习多线程的时候打算做一个简单的多线程socke聊天的程序,结果发现网上的代码都没有完整的实现功能,所以自己实现了一个demo: demo功能大致就是,有一个服务端负责信息转发,多个客户端发送消 ...

  9. Java 多线程Socket编程通讯--实现聊天室代码

    1.创建服务器类 import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import ja ...

随机推荐

  1. 网络测试仪实操手册 RENIX 机框管理

    本文主要阐述信而泰BIGTAO系列 网络测试仪器机框相关操作方法.文章分为机框添加.机框删除.机框重启.机框关机四部分. 第一部分:机框添加 1.添加过程 1.1打开软件 1.2添加端口 1.3输入I ...

  2. 实力再获认可!Smartbi入选爱分析·产业数字化厂商全景报告

    近日,中国独立的第三方产业数字化研究与咨询机构--爱分析发布<2021爱分析·产业数字化厂商全景报告>.思迈特软件凭借优秀的解决方案能力及丰富的业务实践经验,入选报告中银行数字化.保险数字 ...

  3. 【windows 操作系统】进程控制块(PCB)

    转载地址:https://blog.csdn.net/qq_38499859/article/details/80057427一.目录文章目录    操作系统3 ----进程控制块(PCB)详解    ...

  4. Python 中的闭包和自由变量

    1.定义 在函数内部再定义一个函数,并且这个函数用到了外部函数的变量(LEGB),最后返回新建函数的函数名索引,那么将这样的能够访问其定义时所在的作用域的函数以及用到的一些变量称之为闭包.被引用的非全 ...

  5. TCP三次握手中SYN,ACK,seq ack的含义

    转至:https://www.cnblogs.com/muyi23333/articles/13841268.html 1.TCP 为什么三次握手而不是两次握手 1.防止已失效的连接请求又传送到服务器 ...

  6. ansible复习笔记_playbook-从零到无

    --创建时间:2021年3月9日 --修改时间:2021年3月9日 --作者:飞翔的小胖猪 yaml语法格式 每单一文件第一行,使用 "---"开始.在结尾的时候使用三个点&quo ...

  7. 报错:net::err_unknown_url_scheme的解决办法

    在项目中设置了api请求和web页面请求的地址,如下图: 控制台报错,如下图: 问题是:没有加入"http://"这个头,因此访问不到. 解决办法: 再次访问正常

  8. 禁用所有控制台console.log()打印

    在前端dev的环境下,经常会用到console.log()进行调试,以方便开发, 而在产品release的版本中,又不合适在浏览器的console中输出那么多的调试信息. 但是会经常因为没有删除这些开 ...

  9. 【计题04组01号】Java面试问答题

    写作前面 本书内容摘自<Java程序员面试笔试宝典> 很多同学在面试时其实有个误区,认为准备的东西越详细越好 其实不是,就和批试卷一样,写长篇大论其实并不会必然加分 老师阅卷时间有限只会抓 ...

  10. 【FAQ】接入HMS Core推送服务过程中一些常见问题总结

    HMS Core 推送服务(Push Kit)是华为提供的消息推送平台,建立了从云端到终端的消息推送通道.开发者通过集成推送服务,可以向客户端应用实时推送消息,构筑良好的用户关系,提升用户的感知度和活 ...