使用ServerSocket建立聊天服务器(二)
-------------siwuxie095
工程名:TestMyServerSocket
包名:com.siwuxie095.socket
类名:MyServerSocket.java(主类)、ServerListener.java、ChatSocket.java、ChatManager.java
工程结构目录如下:

MyServerSocket.java(主类):
|
package com.siwuxie095.socket; /** * 聊天服务器,不仅能向客户端发送数据,也能从客户端读取数据 * * @author siwux * */ public class MyServerSocket {
/** * 这是主类(主线程),启动线程ServerListener进行监听, * 当有Socket对象进行连接时,在线程ServerListener中 * 启动线程ChatSocket,同时将该ChatSocket线程添加到聊天 * 管理器的集合Vector中 * * @param args */ public static
//运行线程ServerListener,使用匿名对象 new ServerListener().start(); } } |
ServerListener.java:
|
package com.siwuxie095.socket; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import javax.swing.JOptionPane; //创建线程 ServerListener,将有阻塞的代码放到这个独立的线程中 //将新建立的ChatSocket线程添加到集合Vector中 public class ServerListener extends Thread { // 复写run() @SuppressWarnings("resource") @Override public try { // 端口的范围:1~65535,通常都指定较大的数字, // 这样和较小的或系统预留的端口分开 // 有异常抛出,用 try catch 捕获 ServerSocket serverSocket = new ServerSocket(12345);
// ServerSocket创建完成后需要侦听客户端的连接 // 调用accept()方法,这是一个阻塞的方法, // 会阻塞当前的线程,对于有阻塞的代码,应该放到独立的线程中 //(ServerListener 就是一个独立的线程) // 返回值是Socket类型,创建以接收返回值 // 当accept()被执行且socket被赋值,说明有客户端连接 //每当有一个客户端连接到ServerSocket,accept()都会返回一个新的Socket对象 //如果有多个客户端来连接当前的服务器ServerSocket,就会有多个Socket对象出现 //需要一个while循环来循环监听 while (true) {
Socket socket = serverSocket.accept(); // 建立连接时 // 弹出提示框:有客户端连接到本机的 12345 端口 JOptionPane.showMessageDialog(null, "有客户端连接到本机的 12345 端口");
//由于每一个socket要与一个独立的客户端进行通信 //所以要将socket传递给新的线程:ChatSocket(用于Socket通信) //每一个socket都有一个独立的ChatSocket线程 //每一个ChatSocket线程之间是相互独立的,它们不能相互沟通数据 //新建一个类ChatManager,将这些新建的ChatSocket线程管理起来, //实现它们之间的相互通信 //运行该线程 ChatSocket cs=new ChatSocket(socket); cs.start();
//通过静态方法将cs添加到聊天管理器中 ChatManager.getChatManager().add(cs);
}
} catch (IOException e) { e.printStackTrace(); } } } |
ChatSocket.java:
|
package com.siwuxie095.socket; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.io.OutputStreamWriter; import java.io.UnsupportedEncodingException; import java.net.Socket; /** * run()循环执行的读取的工作,即当前的服务器会不断的从客户端读取内容 * 将读取到的内容发送到集合Vector中的所有客户端(除了自身) * * @author siwux * */ //创建用于Socket通信的线程:ChatSocket public class ChatSocket extends Thread {
Socket socket;
//创建构造方法,传入Socket对象 public ChatSocket(Socket socket) { this.socket=socket; }
public
try { //对当前的Socket执行 //使用getOutputStream()获取输出流,通过输出流向外输出数据 //返回值是OutputStream类型,创建以接收返回值 OutputStream os=socket.getOutputStream(); //创建一个BufferedWriter作为数据的输出,传入匿名对象,指定编码,层层包装 BufferedWriter bw=new BufferedWriter(new OutputStreamWriter(os,"UTF-8")); //让BufferedWriter输出字符串 bw.write(out); //因为带缓冲,所以需要强制输出,不然无法输出 bw.flush(); }catch (UnsupportedEncodingException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
//复写run()方法 @Override public
try {
//对Socket的输入流进行包装 //在指定InputStreamReader时,指定编码的字符集 //有异常抛出,用 try catch 捕获 BufferedReader br=new BufferedReader( new InputStreamReader( socket.getInputStream(),"UTF-8"));
String line=null; //读取从客户端发送给服务器的数据 while ((line=br.readLine())!=null) { //通过静态方法,将自己传入,同时传入line ChatManager.getChatManager().publish(this, line); }
//关闭流 br.close(); } catch (IOException e) { e.printStackTrace(); }
} } |
ChatManager.java:
|
package com.siwuxie095.socket; import java.util.Vector; /** * ChatManager 将不同的socket所新建的ChatSocket线程管理起来 * 由于一个聊天服务器只能有一个聊天的管理器:ChatManager * 所以要把这个类作单例化处理 * 单例化的第一步就是让这个类的构造方法变成 private 类型 * * @author siwux * */ public class ChatManager {
//让构造方法变成private类型,完成单例化的第一步 private ChatManager(){}
//为当前类创建一个实例 private static final ChatManager cm=new ChatManager();
//创建方法 getChatManager(),返回ChatManager类型 public static ChatManager getChatManager() { return cm; }
//至此,完成了这个类(ChatManager)的单例化 //接下来就是对ChatSocket线程进行管理
//创建一个Vector,指定泛型为ChatSocket Vector<ChatSocket> vector=new Vector<>();
//创建add()方法,为当前集合添加一个新的ChatSocket对象 //在创建ChatSocket时使用,即ServerListener.java中使用 public //调用Vector的add()方法,传入cs即可 vector.add(cs); }
//创建publish()方法,其中的某个ChatSocket线程可以调用publish() //向其他的客户端(其他的ChatSocket线程)发送信息 //传入线程本身和需要发送的信息 public
//因为要发送给集合Vector中的其他所有线程,要使用遍历 for (int i = 0; i < vector.size(); i++) { //获取循环中的第 i 个对象 ChatSocket csx=vector.get(i);
//当前发送信息的线程就不用再接收这条信息, //判断发送消息的对象是不是当前对象 if (!cs.equals(csx)) { csx.output(msg); } } }
} |
运行后,终止按钮(Terminate)长亮,即 当前程序正在运行 且 没有停止

而且,此时也没有任何提示框,即当前程序被阻塞在
ServerListener.java 的:
Socket socket=serverSocket.accept();
打开
CMD 窗口,输入:telnet 127.0.0.1 12345
或
telnet localhost 12345
(即
本机地址+端口),回车。此时,会弹框提示:

点击确定
打开多个
CMD 窗口,重复操作,然后在其中一个 CMD 窗口任意输入,
其他窗口就会显示该输入

点击
终止按钮(Terminate),可结束运行
【made by siwuxie095】
使用ServerSocket建立聊天服务器(二)的更多相关文章
- Socket 基础解析使用ServerSocket建立聊天服务器
很简单的教程哦! 1.socket 简介 Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求.ServerSocket 用于 ...
- 使用 ServerSocket 建立聊天服务器-1
1.代码目录 2.ChatSocket.java --------------------------------------------------------------------------- ...
- 使用ServerSocket建立聊天服务器(一)
-------------siwuxie095 工程名:TestMyServerSocket 包名:com.siwuxie095.socket ...
- 使用 ServerSocket 建立聊天服务器-2
1. 从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新 ...
- 使用Java建立聊天客户端
---------------siwuxie095 关于 聊天服务器,详见本人博客的分类:来一杯Java, 里面的 使用ServerSocket ...
- openfire:基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件
基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件 上一篇文章介绍到怎么在自己的Java环境中搭建openfire插件开发的环境,同时介绍到怎样一步步简单的开发openfir ...
- 基于开源 Openfire 聊天服务器 - 开发Openfire聊天记录插件
原文:http://www.cnblogs.com/hoojo/archive/2013/03/29/openfire_plugin_chatlogs_plugin_.html 随笔-150 评论- ...
- socket实现聊天功能(二)
socket实现聊天功能(二) WebSocket协议是建立在HTTP协议之上,因此创建websocket服务时需要调用http模块的createServer方法.将生成的server作为参数传入so ...
- 使用rabbitmq实现集群im聊天服务器消息的路由
这个地址图文会更清晰:https://www.jianshu.com/p/537e87c64ac7 单机系统的时候,客户端和连接都有同一台服务器管理. image.png 在本地维护一份userI ...
随机推荐
- 八大排序算法原理以及Java实现(直接插入排序)
概述 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存. 我们这里说说八大排序就是内部排序. 当n较大, ...
- power designer 设计数据库生成到oracle数据库
一.概念模型设计 1. 创建工程,创建概念设计模型,在快捷菜单栏调出 palette 找到表格工具,在主界面中创建表格. 2. 创建出的表格,双击进入设计模式 -------------------- ...
- 是因为Session只能让服务器在一次连续的会话中记住你,而Cookie是记住浏览器一段时间
Cookie的作用 因为http协议先天不足是无记忆性. 还有一个区别是:Session是服务器端保存会话状态的机制. 而Cookie则是浏览器端保存会话的机制. Cookie 的应用
- H5实现登录
1.主要就是获取cookie并每次发送请求时都带着:登录请求 2.添加HTTP Cookie管理器 3.登录请求时,加正则表达式提取器 取出返回的cookie ①使用charles抓包查看cookie ...
- visual assist(VA)设置快捷键(其它安装的插件设置快捷键也在这里)
安装完visual assist后发现快捷键无法使用纠结,然后找如何去设置快捷建以此记录一下: 在Tools-->customize-->Keyboard-->Add-ins 常用的 ...
- C8051F340 USB Fn hacking
/************************************************************************************ * C8051F340 US ...
- ZOJ Anagrams by Stack(堆栈中的搜索)
个人心得:算法书中的第一个例题就来了一个下马威,虽然题意很好理解但是做起来确实这么不顺手,所以自己对于搜索和堆栈理解的并不是很好, 以前也是很多这样的题目无法实施,这题要做的很明确就是输出正确的能依靠 ...
- 巧用padding让图片宽高比固定并自适应布局
1.从上图知道原始图片大小是 800 * 250,即宽高比为 3.2: 2.html 及 css 代码如下, 可以知道就只是在一个div里面放了一张图片,那么如何让这张图片的宽高比固定呢,看了css之 ...
- 为什么很多公司招聘前端开发要求有 Linux / Unix 下的开发经验?
知乎: http://www.zhihu.com/question/19666395
- Windows平台下gitbook的安装与使用
最近要用到gitbook去阅读电子书,整理了一份在windows系统下安装gitbook的过程. * 安装nodejs * 安装cnpm * 搭建gitbook平台 1.在windows上安装node ...