热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Socket通信(二)--多线程服务器实现

Socket通信(二)--多线程服务器实现在我的上一篇博客点击打开链接中,实现了一个简单的类qq聊天功能。然而日常生活中通常一台服务器部署好后,会有成百上千的客户端对其进行访问,那么这样的功能又该如

Socket通信(二)-- 多线程服务器实现

在我的上一篇博客点击打开链接中,实现了一个简单的类qq聊天功能。然而日常生活中通常一台服务器部署好后,会有成百上千的客户端对其进行访问,那么这样的功能又该如何实现呢。下文对此多线程通信作一个说明。




服务端Socket具体代码为:


public class Server {
public static void main(String[] args) {
ServerSocket server=null;
try {
//创建一个服务器端socket,即ServerSocket,绑定指定的端口,并监听此端口
server=new ServerSocket(8888);
int count=0;//记录客户端的数量
System.out.println("***服务器端启动,等待客户端的连接***");
Socket socket=null;
//循环监听客户端的连接
while(true){
//调用accept()方法开始监听,等待客户端的连接
socket=server.accept();
ServerThread st=new ServerThread(socket);
st.start();
count++;
System.out.println("当前客户端连接数为:"+count);
InetAddress inetAddress=socket.getInetAddress();
System.out.println("当前客户端地址为:"+inetAddress.getHostName());
}
} catch (IOException e) {
e.printStackTrace();
}
}
}


服务端针对每一个客户端都会单独开启一个线程处理响应的请求,线程类为:


public class ServerThread extends Thread {
//创建和本线程相关的socket
Socket socket=null;
public ServerThread(Socket socket){
this.socket=socket;
}
//线程执行的操作,响应客户端的请求
public void run(){
InputStream is = null;
InputStreamReader isr = null;
BufferedReader br = null;
OutputStream os = null;
PrintWriter pw = null;
try {
//获取输入流,读取客户端信息
is = socket.getInputStream();
isr = new InputStreamReader(is);
br = new BufferedReader(isr);
String info=null;
while((info=br.readLine())!=null){
System.out.println("我是服务端,客户端说"+info);//循环读取客户端信息
}
socket.shutdownInput();//关闭输入流
//获取输出流,响应客户端信息
os = socket.getOutputStream();
pw = new PrintWriter(os);
pw.write("欢迎您");
pw.flush();
socket.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
} finally{
//关闭相关资源
try {
if(pw!=null)
pw.close();
if(os!=null)
os.close();
if(br!=null)
br.close();
if(isr!=null)
isr.close();
if(is!=null)
is.close();
if(socket!=null)
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

客户端代码为:


public class Client {
public static void main(String[] args) {
try {
//1.创建一个客户端socket,制定地址和端口
Socket client=new Socket("localhost", 8888);
//2.获取输出流,向服务器发送信息
OutputStream os=client.getOutputStream();//字节输出流
PrintWriter pw=new PrintWriter(os);//将字节流包装为打印流
pw.write("用户名为:admin,密码为:123");
pw.flush();
client.shutdownOutput();
//3.获取输入流,输出客户端响应信息
InputStream is=client.getInputStream();
InputStreamReader isr=new InputStreamReader(is);
BufferedReader br=new BufferedReader(isr);
String info=null;
while((info=br.readLine())!=null){
System.out.println("我是客户端,服务端说"+info);//循环读取服务端响应信息
}
client.shutdownInput();//关闭输入流
//4.关闭相关资源
br.close();
isr.close();
is.close();
pw.close();
os.close();
client.close();
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}


首先启动server端,显示如下:




启动一个服务端后,server端显示如下:




再启动一个服务端后,server端显示为:





推荐阅读
  • Java Socket 关键参数详解与优化建议
    Java Socket 的 API 虽然被广泛使用,但其关键参数的用途却鲜为人知。本文详细解析了 Java Socket 中的重要参数,如 backlog 参数,它用于控制服务器等待连接请求的队列长度。此外,还探讨了其他参数如 SO_TIMEOUT、SO_REUSEADDR 等的配置方法及其对性能的影响,并提供了优化建议,帮助开发者提升网络通信的稳定性和效率。 ... [详细]
  • Python 伦理黑客技术:深入探讨后门攻击(第三部分)
    在《Python 伦理黑客技术:深入探讨后门攻击(第三部分)》中,作者详细分析了后门攻击中的Socket问题。由于TCP协议基于流,难以确定消息批次的结束点,这给后门攻击的实现带来了挑战。为了解决这一问题,文章提出了一系列有效的技术方案,包括使用特定的分隔符和长度前缀,以确保数据包的准确传输和解析。这些方法不仅提高了攻击的隐蔽性和可靠性,还为安全研究人员提供了宝贵的参考。 ... [详细]
  • 在Android平台中,播放音频的采样率通常固定为44.1kHz,而录音的采样率则固定为8kHz。为了确保音频设备的正常工作,底层驱动必须预先设定这些固定的采样率。当上层应用提供的采样率与这些预设值不匹配时,需要通过重采样(resample)技术来调整采样率,以保证音频数据的正确处理和传输。本文将详细探讨FFMpeg在音频处理中的基础理论及重采样技术的应用。 ... [详细]
  • 在处理 XML 数据时,如果需要解析 `` 标签的内容,可以采用 Pull 解析方法。Pull 解析是一种高效的 XML 解析方式,适用于流式数据处理。具体实现中,可以通过 Java 的 `XmlPullParser` 或其他类似的库来逐步读取和解析 XML 文档中的 `` 元素。这样不仅能够提高解析效率,还能减少内存占用。本文将详细介绍如何使用 Pull 解析方法来提取 `` 标签的内容,并提供一个示例代码,帮助开发者快速解决问题。 ... [详细]
  • 本文探讨了如何利用Java代码获取当前本地操作系统中正在运行的进程列表及其详细信息。通过引入必要的包和类,开发者可以轻松地实现这一功能,为系统监控和管理提供有力支持。示例代码展示了具体实现方法,适用于需要了解系统进程状态的开发人员。 ... [详细]
  • 在Java Web服务开发中,Apache CXF 和 Axis2 是两个广泛使用的框架。CXF 由于其与 Spring 框架的无缝集成能力,以及更简便的部署方式,成为了许多开发者的首选。本文将详细介绍如何使用 CXF 框架进行 Web 服务的开发,包括环境搭建、服务发布和客户端调用等关键步骤,为开发者提供一个全面的实践指南。 ... [详细]
  • 在本地环境中部署了两个不同版本的 Flink 集群,分别为 1.9.1 和 1.9.2。近期在尝试启动 1.9.1 版本的 Flink 任务时,遇到了 TaskExecutor 启动失败的问题。尽管 TaskManager 日志显示正常,但任务仍无法成功启动。经过详细分析,发现该问题是由 Kafka 版本不兼容引起的。通过调整 Kafka 客户端配置并升级相关依赖,最终成功解决了这一故障。 ... [详细]
  • 在Linux系统中,网络配置是至关重要的任务之一。本文详细解析了Firewalld和Netfilter机制,并探讨了iptables的应用。通过使用`ip addr show`命令来查看网卡IP地址(需要安装`iproute`包),当网卡未分配IP地址或处于关闭状态时,可以通过`ip link set`命令进行配置和激活。此外,文章还介绍了如何利用Firewalld和iptables实现网络流量控制和安全策略管理,为系统管理员提供了实用的操作指南。 ... [详细]
  • 题目要求维护一个数列,并支持两种操作:一是查询操作,语法为QL,用于查询数列末尾L个数中的最大值;二是更新操作,用于修改数列中的某个元素。本文通过ST表(Sparse Table)优化查询效率,确保在O(1)时间内完成查询,同时保持较低的预处理时间复杂度。 ... [详细]
  • 深入探索HTTP协议的学习与实践
    在初次访问某个网站时,由于本地没有缓存,服务器会返回一个200状态码的响应,并在响应头中设置Etag和Last-Modified等缓存控制字段。这些字段用于后续请求时验证资源是否已更新,从而提高页面加载速度和减少带宽消耗。本文将深入探讨HTTP缓存机制及其在实际应用中的优化策略,帮助读者更好地理解和运用HTTP协议。 ... [详细]
  • 利用 fopen、fwrite、fread、fseek 和 fclose 实现文件中整型数据的读写操作 ... [详细]
  • 本文介绍了如何利用 Delphi 中的 IdTCPServer 和 IdTCPClient 控件实现高效的文件传输。这些控件在默认情况下采用阻塞模式,并且服务器端已经集成了多线程处理,能够支持任意大小的文件传输,无需担心数据包大小的限制。与传统的 ClientSocket 相比,Indy 控件提供了更为简洁和可靠的解决方案,特别适用于开发高性能的网络文件传输应用程序。 ... [详细]
  • 经过两天的努力,终于成功解决了半平面交模板题POJ3335的问题。原来是在`OnLeft`函数中漏掉了关键的等于号。通过这次训练,不仅加深了对半平面交算法的理解,还提升了调试和代码实现的能力。未来将继续深入研究计算几何的其他核心问题,进一步巩固和拓展相关知识。 ... [详细]
  • 本文介绍了如何利用ObjectMapper实现JSON与JavaBean之间的高效转换。ObjectMapper是Jackson库的核心组件,能够便捷地将Java对象序列化为JSON格式,并支持从JSON、XML以及文件等多种数据源反序列化为Java对象。此外,还探讨了在实际应用中如何优化转换性能,以提升系统整体效率。 ... [详细]
  • Java中不同类型的常量池(字符串常量池、Class常量池和运行时常量池)的对比与关联分析
    在研究Java虚拟机的过程中,笔者发现存在多种类型的常量池,包括字符串常量池、Class常量池和运行时常量池。通过查阅CSDN、博客园等相关资料,对这些常量池的特性、用途及其相互关系进行了详细探讨。本文将深入分析这三种常量池的差异与联系,帮助读者更好地理解Java虚拟机的内部机制。 ... [详细]
author-avatar
ivanjjHelen
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有