-
运行在服务端的ServerSocket有两个作用
-
1.申请服务端口(客户端通过该端口与服务端建立连接)
-
2.监听服务端口,等待客户端连接,一旦客户端连接则
-
创建一个Socket实例用于与该客户端交互.
*/
private ServerSocket server;
/*
*该集合用于保存所以客户端的Socket(数据流)
*/
private List allOut;
public Server() throws Exception{
try {
allOut = new ArrayList();
/*
-
实例化ServerSocket需要指定
-
服务端口.该端口不能与当前操作系统
-
其他程序申请的端口冲突,否则会抛出
-
端口被占用异常
*/
server = new ServerSocket(8088);
} catch (Exception e) {
throw e;
}
}
/**
- 将给定的输出流存入共享集合
*/
private synchronized void addOut(PrintWriter out){
allOut.add(out);
}
/**
- 将给定的输出流从共享集合中删除
*/
private synchronized void removeOut(PrintWriter out){
allOut.remove(out);
}
/**
- 将给定的消发送给所以的客户端
*/
private synchronized void sendMessage(String message){
for(PrintWriter out :allOut){
out.println(message);
}
}
public void start() {
try {
/*
-
ServerSocket提供一个方法:
-
Socket accept()
-
该方法是一个阻塞方法,作用是监听
-
ServerSocket开启的服务端口,
-
直到一个客户端通过该端口连接,该方法
-
才会解除阻塞,并返回一个Socket实例
-
通过该Socket实例与刚刚建立连接的
-
客户端进行通信.
*/
while (true) {
System.out.println(“等待客户端连接…”);
Socket socket = server.accept();
System.out.println(“一个客户端连接了!”);
/*
*当一个客户端连接后,启动一个线程来处理
*与该客户端的交互工作.
*/
ClientHandlerWriter clientHandler = new ClientHandlerWriter(socket);
Thread t = new Thread(clientHandler);
t.start();
ClientHandlerRead clientHandler2 = new ClientHandlerRead(socket);
Thread t2 = new Thread(clientHandler2);
t2.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
try {
Server server = new Server();
server.start();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
-
该线程负责与指定的客户端进行交互
-
@author Cher_du
*/
class ClientHandlerWriter implements Runnable{
/**
- 当前线程负责与指定客户端交互的Socket
*/
private Socket socket;
//客户端的地址信息
private String host;
public ClientHandlerWriter(Socket socket){
this.socket = socket;
/*
-
通过socket获取远程计算机地址信息
-
对于服务端而言,远程计算机就是客户端
*/
InetAddress address = socket.getInetAddress();
//获取远端计算机的IP
host = address.getHostAddress();
}
@Override
public void run() {
PrintWriter pw = null;
try {
/*
*通过Socket创建输出流,用于将消息
*发送给客户端
*/
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,“utf-8”);
pw = new PrintWriter(osw,true);
/*
-
br.readLine读取客户端发送过来的一行字符串
-
时,客户端断开连接时,由于客户端所在系统不同,
-
这里readLine方法的执行结果也不相同:
-
当windows的客户端断开连接时,readLine方法
-
会直接抛出异常
-
当Linux的客户端断开连接时,readLine方法会
-
返回null.
*/
// while((message = br.readLine())!=null){
// System.out.println(host+“说:”+message);
// //pw.println(host+“说:”+message);
// //转发给所有客户端
// sendMessage(host+“说:”+message);
// }
Scanner scanner = new Scanner(System.in);
String message = null;
while (true) {
message = scanner.nextLine();
pw.println(message);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
class ClientHandlerRead implements Runnable{
/**
- 当前线程负责与指定客户端交互的Socket
*/
private Socket socket;
//客户端的地址信息
private String host;
public ClientHandlerRead(Socket socket){
this.socket = socket;
/*
-
通过socket获取远程计算机地址信息
-
对于服务端而言,远程计算机就是客户端
*/
InetAddress address = socket.getInetAddress();
//获取远端计算机的IP
host = address.getHostAddress();
}
@Override
public void run() {
PrintWriter pw = null;
try {
sendMessage(host+“上线了!”);
/*
*通过Socket创建输出流,用于将消息
*发送给客户端
*/
OutputStream out = socket.getOutputStream();
OutputStreamWriter osw = new OutputStreamWriter(out,“utf-8”);
pw = new PrintWriter(osw,true);
//将该客户端的输出流存入共享集合
addOut(pw);
InputStream in = socket.getInputStream();
InputStreamReader isr = new InputStreamReader(in,“UTF-8”);
BufferedReader br = new BufferedReader(isr);
String message = null;
/*
-
br.readLine读取客户端发送过来的一行字符串
-
时,客户端断开连接时,由于客户端所在系统不同,
-
这里readLine方法的执行结果也不相同:
-
当windows的客户端断开连接时,readLine方法
-
会直接抛出异常
-
当Linux的客户端断开连接时,readLine方法会
-
返回null.
*/
while((message = br.readLine())!=null){
System.out.println(host+“说:”+message);
//pw.println(host+“说:”+message);
//转发给所有客户端
//sendMessage(host+“说:”+message);
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//客户端与服务端断开连接.
//客户端下线后从共享集合中删除输出流
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
最后
权威指南-第一本Docker书
引领完成Docker的安装、部署、管理和扩展,让其经历从测试到生产的整个开发生命周期,深入了解Docker适用于什么场景。并且这本Docker的学习权威指南介绍了其组件的基础知识,然后用Docker构建容器和服务来完成各种任务:利用Docker为新项目建立测试环境,演示如何使用持续集成的工作流集成Docker,如何构建应用程序服务和平台,如何使用Docker的API,如何扩展Docker。
总共包含了:简介、安装Docker、Docker入门、使用Docker镜像和仓库、在测试中使用Docker、使用Docker构建服务、使用Fig编配Docke、使用Docker API、获得帮助和对Docker进行改进等9个章节的知识。
关于阿里内部都在强烈推荐使用的“K8S+Docker学习指南”—《深入浅出Kubernetes:理论+实战》、《权威指南-第一本Docker书》,看完之后两个字形容,爱了爱了!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
ker。
总共包含了:简介、安装Docker、Docker入门、使用Docker镜像和仓库、在测试中使用Docker、使用Docker构建服务、使用Fig编配Docke、使用Docker API、获得帮助和对Docker进行改进等9个章节的知识。
[外链图片转存中…(img-Tk4KgcGI-1712027649067)]
[外链图片转存中…(img-W2z5zzp8-1712027649067)]
[外链图片转存中…(img-Sz8Fg3AY-1712027649068)]
[外链图片转存中…(img-EnuGKU7m-1712027649068)]
关于阿里内部都在强烈推荐使用的“K8S+Docker学习指南”—《深入浅出Kubernetes:理论+实战》、《权威指南-第一本Docker书》,看完之后两个字形容,爱了爱了!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!