Socket 基础解析使用ServerSocket建立聊天服务器
很简单的教程哦!
1.socket 简介
Socket 又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。ServerSocket 用于服务器端,Socket 是建立网络连接时使用的。在连接成功时,应用程序两端都会产生一个 Socket 实例,操作这个实例,完成所需的会话。
2.ServerSocket 的建立与使用
最简单的建立服务器ServerSocket
public class MyServerSocket {
public static void main(String[] args) {
try {
//1-65535 监听12345端口
ServerSocket serverSocket = new ServerSocket(12345);
//监听客户端链接,调用accept()方法 accept方法是一个阻塞的方法,会阻塞当前线程
Socket socket = serverSocket.accept();
//客户端有请求时,弹出提示框
JOptionPane.showMessageDialog(null, "有客户链接到了本机的12345端口");
} catch (IOException e) {
e.printStackTrace();
}
}
}
运行该代码,会发现程序阻塞在serverSocket.accept()处,打开浏览器请求127.0.0.1:12345 会有弹窗,程序结束

3.使用 ServerSocket 建立聊天服务器-1
上述方法是不合理的,因为accept()方法会造成程序阻塞,这样,主线程就会被阻塞,对于阻塞的代码,需要放置到独立线程中,修改如下
public class MyServerSocket {
public static void main(String[] args) {
new ServerListener().start();
}
}
监听链接的线程
/**
* 监听连接的线程
*/
public class ServerListener extends Thread{
@Override
public void run() {
try {
//1-65535 监听12345端口
ServerSocket serverSocket = new ServerSocket(12345);
//监听客户端链接,调用accept()方法 accept方法是一个阻塞的方法,会阻塞当前线程 //每当有一个客户端连接到当前的serversocket就会返回一个新的socket对象,所以当有多个的时候
//就要创建一个while循环来监听来自客户端的链接
while (true) {//true,让他一直处于循环,不会结束
Socket socket = serverSocket.accept();
//客户端有请求时,弹出提示框
JOptionPane.showMessageDialog(null, "有客户链接到了本机的12345端口");
//由于每个socket又要与独立的客户端进行通讯,所以将socket传递给新的线程
new ChatSocket(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
} }
用于通讯的线程
/**
* 创建用于socket通信的线程
*/
public class ChatSocket extends Thread { Socket socket;//本地需要有socket来接受传入的s值 public ChatSocket(Socket s){
this.socket=s;
} public void out(String out){
try {
// 执行数据的输出和相关功能的包装
socket.getOutputStream().write(out.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void run() {
int count = 0;
while (true) {
count++;
out("loop:"+count);
try {
sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
此时一个线程版的socket通信就算结束了,打开cmd 输入telnet localhost 12345会有惊喜哦
这种惊喜('telnet' 不是内部或外部命令,也不是可运行的程序)的自行百度
此时可以同时打开多个cmd 效果相同

4.使用 ServerSocket 建立聊天服务器-2
以上是一个简单的socket聊天服务器,但是当前的服务器只有向客户端发送数据的功能,并没有从客户端读取数据的功能!
每个ChatSocket线程都是独立的,不能相互共同数据,建立ChatManager沟通所有数据,代码修改如下:
public class MyServerSocket {
public static void main(String[] args) {
new ServerListener().start();
}
}
监听链接的线程
/**
* 监听连接的线程
*/
public class ServerListener extends Thread{
@Override
public void run() {
try {
//1-65535 监听12345端口
ServerSocket serverSocket = new ServerSocket(12345);
//监听客户端链接,调用accept()方法 accept方法是一个阻塞的方法,会阻塞当前线程 //每当有一个客户端连接到当前的serversocket就会返回一个新的socket对象,所以当有多个的时候
//就要创建一个while循环来监听来自客户端的链接
while (true) {//true,让他一直处于循环,不会结束
Socket socket = serverSocket.accept();
//客户端有请求时,弹出提示框
JOptionPane.showMessageDialog(null, "有客户链接到了本机的12345端口");
//由于每个socket又要与独立的客户端进行通讯,所以将socket传递给新的线程
ChatSocket cs = new ChatSocket(socket);
cs.start();
ChatManager.getChatManager().add(cs);
}
} catch (IOException e) {
e.printStackTrace();
}
} }
创建用于socket通信的线程
/**
* 创建用于socket通信的线程
*/
public class ChatSocket extends Thread { Socket socket;//本地需要有socket来接受传入的s值 public ChatSocket(Socket s){
this.socket=s;
} public void out(String out){
try {
// 执行数据的输出和相关功能的包装
socket.getOutputStream().write(out.getBytes("UTF-8"));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} @Override
public void run() {//run方法中加入接收数据的功能
try {
BufferedReader br = new BufferedReader(
new InputStreamReader(
socket.getInputStream(),"UTF-8"));
String line = null;
while ((line = br.readLine())!=null) {//客户端的数据
//发给聊天室的所有人
ChatManager.getChatManager().publish(this, line);
}
br.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
聊天管理类
/**
* 聊天管理类
*/
public class ChatManager { //单例化该ChatManager
private ChatManager(){}
private static final ChatManager cm = new ChatManager();
public static ChatManager getChatManager(){
return cm;
}
Vector<ChatSocket> vector = new Vector<ChatSocket>(); public void add(ChatSocket cs){
vector.add(cs);
} public void publish(ChatSocket cs,String out){
for(int i=0;i<vector.size();i++){
ChatSocket cschatSocket = vector.get(i);
if(!cs.equals(cschatSocket)){//发送消息的对象不接受消息本身
cschatSocket.out(out);
}
}
}
}
打开多个cmd,实现聊天功能,无论在哪个终端发,都能接收到消息

Socket 基础解析使用ServerSocket建立聊天服务器的更多相关文章
- 使用 ServerSocket 建立聊天服务器-1
1.代码目录 2.ChatSocket.java --------------------------------------------------------------------------- ...
- 使用ServerSocket建立聊天服务器(一)
-------------siwuxie095 工程名:TestMyServerSocket 包名:com.siwuxie095.socket ...
- 使用ServerSocket建立聊天服务器(二)
-------------siwuxie095 工程名:TestMyServerSocket 包名:com.siwuxie095.socket 类名:M ...
- 使用 ServerSocket 建立聊天服务器-2
1. 从serverListener中可以看出,每一个客户端创建新的请求之后,都会把它分配给一个独立的chatsocket ,但是每一个ChatSocket都是相互独立的,他们之间并不能沟通,所以要新 ...
- 使用Java建立聊天客户端
---------------siwuxie095 关于 聊天服务器,详见本人博客的分类:来一杯Java, 里面的 使用ServerSocket ...
- Socket Server-基于线程池的TCP服务器
了解线程池 在http://blog.csdn.net/ns_code/article/details/14105457(读书笔记一:TCP Socket)这篇博文中,服务器端采用的实现方式是:一个客 ...
- 从零开始的Python学习Episode 21——socket基础
socket基础 网络通信要素: A:IP地址 (1) 用来标识网络上一台独立的主机 (2) IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段.主机号:用于识别该网络中的 ...
- Python学习 :socket基础
socket基础 什么是socket? - socket为接口通道,内部封装了IP地址.端口.协议等信息:我们可以看作是以前的通过电话机拨号上网的年代,socket即为电话线 socket通信流程 我 ...
- 【Java TCP/IP Socket】基于线程池的TCP服务器(含代码)
了解线程池 在http://blog.csdn.net/ns_code/article/details/14105457(读书笔记一:TCP Socket)这篇博文中,服务器端采用的实现方式是:一个客 ...
随机推荐
- ios蓝牙开发(二)ios连接外设的代码实现
上一篇文章介绍了蓝牙的技术知识,这里我们具体说明一下中心模式的应用场景.主设备(手机去扫描连接外设,发现外设服务和属性,操作服务和属性的应用.一般来说,外设(蓝牙设备,比如智能手环之类的东西), 会由 ...
- SASS组件开发
*:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !important; } /* ...
- 简单的web三层架构系统【第一版】
SQLhelper助手类编写: 1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using Sys ...
- C#复习三(Day 22)
哈哈,又到了总结的时间了.今天还是在继续复习C#的基础语法.这次总结主要以一下小程序为主. Split()的运用 123-456---789-----123-2把类似的字符串中重复符号去掉,得到123 ...
- C# 微信公众平台开发(2)-- 微信菜单
上一篇了解微信开发者中心 URL的配置验证: 验证成功后,就可以对获取的接口权限进行操作 自定义菜单接口可实现多种类型按钮,用的比较多的是 1.click:点击推事件 用户点击click类型按钮后,微 ...
- window.parent与window.opener的区别与使用
window.parent 是iframe页面调用父页面对象 举例: a.html 如果我们需要在b.html中要对a.html中的username文本框赋值(就如很多上传功能,上传功能页在ifrma ...
- HDU 2087 剪花布条(模式串在主串中出现的次数主串中子串不可重叠)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2087 题意:求模式串在主串中出现的次数,与模式串匹配的子串之间不可重叠. 思路:用kmp算法解决,在匹 ...
- java 读文件 解析
[Java]读取文件方法大全 1.按字节读取文件内容2.按字符读取文件内容3.按行读取文件内容 4.随机读取文件内容 public class ReadFromFile { /** ...
- IOS 表视图(UITableVIew)的使用方法(2)名单的分段显示
我们可以采用名字分段法,名字分段会在之后的小节中显示,这是转而使用球员的角色分段发,以最直接的入手点讲解好UITableView的分段使用方法.本节示例时基于上节的SimpleTableViewCon ...
- ORA-20000: ORU-10027: buffer overflow, limit of 10000 bytes
要用dbms_output.put_line来输出语句,遇到以下错误: ERROR 位于第 1 行: ORA-20000: ORU-10027: buffer overflow, limit ...