之前的代码中关闭了 socket 对象的输入流与输出流,但并没有关闭掉socket 对象,会造成服务器资源的浪费,应通过调用 socket 的 close() 方法来关闭当前的socket 对象。

因此,可以通过创建一个  ServerScanThread 线程,使其一直在后台运行,扫描看哪些 socket 对象的 Input Stream 与 OutputStream 均已关闭,当扫描到当前 socket 对象的输入输出流均已关闭,则关闭当前 socket 对象。

扫描线程代码:

public class ServerScanThread extends Thread {
public static List<Socket> socketList = new LinkedList<Socket>(); //实例化一个静态列表,使其存放 Socket,使用LinkedList 便于删除
public ServerScanThread(){
setDaemon(true);//设置为后台线程
start();
}
public void run(){
while(true){
//1.我要去扫描整个集合,如果当前集合是空的,我就去睡觉去喽
while(socketList == null ||socketList.size()<= 0){
System.out.println("这会儿集合里没有socket,我先睡觉10s");//测试代码
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }
//2.如果运行到这里,则说明 socketList 中有元素,则有开始扫描判断其socket 对象是否已经关闭了其输入流和输入流。
for(int i = 0;i<socketList.size();i++){
Socket socket = socketList.get(i);//从socketList 集合中获得一个 socket 对象。
if(socket.isInputShutdown() & socket.isOutputShutdown()){
try {
socket.close();//关闭当前 socket 对象
socketList.remove(i);//从当前列表中移除当前 socket 对象。
System.out.println("有一个 socket 被关闭了");//测试代码
//i--; LinkedList在移除掉一个元素后,其后边的元素下标统统会减一,为保证不会跳过某一个元素,可在此处将 i 自减,也可以不因为会进行再次扫描
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
try { Thread.sleep(5000);//扫描完一遍之后休息五秒钟
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} }//整个线程完成后可以在 Server 中进行调用。 } }

服务器端代码:

public class Server1 {

    public static void main(String[] args) {
Scanner input = new Scanner(System.in); try { @SuppressWarnings("resource")
ServerSocket server = new ServerSocket(9880);
new ServerScanThread();
while (true){
Socket client = server.accept();
ServerScanThread.socketList.add(client);//在 socketList 集合中加入 socket 实例对象
System.out.println("来自"+ client.getInetAddress().getHostAddress()+"的客户端已连接成功!");
if(client != null){
//开始对话 new WriterThread("服务端",client);
new ReaderThread("服务端",client); }
}
} catch (IOException e) {
e.printStackTrace();
} input.close(); } }
  • 当没有客户端运行时的输出:

此时没有socket对象,程序不停在内部的第一个while 循环里运行,每隔十秒打印一次。

  • 当运行客户端但不关闭socket 的输入输出流时的输出:

由于是先运行的服务器端,所以while 循环先会执行一次,这次循环中还没有socket 对象,当客户端开始运行时,由于没有输入 byebye ,所以不会关闭 socket 的输入流与输出流,程序会执行到内部 for 循环不断循环。

  • 当运行客户端并且关闭socket 的输入输出流时的输出:

在两端分别输入 byebye 关闭输入输出流之后,当前socket被扫描出来并关闭。因为设置的该扫描线程为一个后台线程,当 Server 停止运行时,该线程也停止。

如有不对之处,还望指正,谢谢(●'◡'●)

Java SE ——TCP协议网络编程(三)的更多相关文章

  1. JavaSE——TCP协议网络编程(一)

    实现客户端与服务端的连接: 创建TCP服务端的 ServerSocket ServerSocket :此类实现服务器套接字.服务器套接字请求通过网络传入,基于该请求执行某些操作,然后可能向请求者返回结 ...

  2. Qt基于tcp协议网络编程

    基于Qt网络编程: 基于tcp协议 c/s模式编程 所需要的类:QTcpServer QTcpSocket 利用qt基于tcp协议编写c/s模式程序: 两个类中的信号: QTcpServer : ne ...

  3. 基于TCP协议网络编程

    1.TCP/IP是一种可靠的网络协议,它在通信的两端各建立一个Socket,从而在通信的两端之间形成网络虚拟链路: 一旦建立了虚拟的网络链路,两端的程序就可以通过虚拟链路来进行通信: 2.Java对基 ...

  4. JavaSE——TCP协议网络编程(二)

    1.Java网络编程与多线程的综合应用: 类Socket提供了方法getInputStream ()和getOutStream()来得到对应的输入/输出流以进行读/写操作,这两个方法分别返回Input ...

  5. TCP/IP协议网络编程以及UDP和TCP之传输协议

    1.什么是TCP/IP协议? 网络编程协议有很多,目前应用最广泛的是TCP/IP协议(Transmission Control Protocal/Internet Protoal 传输控制协议/英特网 ...

  6. (1)线程的同步机制 (2)网络编程的常识 (3)基于tcp协议的编程模型

    1.线程的同步机制(重点)1.1 基本概念 当多个线程同时访问同一种共享资源时可能会造成数据的覆盖和不一致等问题,此时就需要对线程之间进行协调和通信,该方式就叫线程的同步机制. 如: 2003年左右 ...

  7. (1)网络编程的常识 (2)基于tcp协议的编程模型 (3)tcp协议和udp协议的比较 (4)基于udp协议的编程模型

    1.网络编程的常识 目前主流的网络通讯软件有:微信.QQ.YY.陌陌.探探.飞信.阿里旺旺.... 在吗? 1.1 七层网络模型(熟悉) 为了保证数据传递的可靠安全等等,ISO(国际标准委员会组织)将 ...

  8. TCP/IP网络编程之套接字类型与协议设置

    套接字与协议 如果相隔很远的两人要进行通话,必须先决定对话方式.如果一方使用电话,另一方也必须使用电话,而不是书信.可以说,电话就是两人对话的协议.协议是对话中使用的通信规则,扩展到计算机领域可整理为 ...

  9. TCP/IP协议-网络编程

    本文转载自公众号“呆呆熊一点通”,作者:呆呆 开篇语 前两年, 就买了<TCP/IP网络编程>这本书, 由于自身基础薄弱, 只是走马观花翻阅了几张. 后来工作了这些年, 越来越感到瓶颈期已 ...

随机推荐

  1. Entity Framework 丢失数据链接的绑定,在已绑好的EDMX中提示“Choose Your Data Connection”

    早先做的一个练手的项目中, 使用到了Entity framework . 最近碰到一个问题,在edmx 里面选择“Update model from Database” 的时候提示了 “Choose ...

  2. js实现是倒计时功能

    工作中经常用到倒计时的功能,最近在整理之前做的项目的时候,发现自己写过一个倒计时的功能的效果,这里和大家分享下!实现这个功能是用原生js写的,不需要加载额外的库文件!功能比较简单,但是可以在此基础上扩 ...

  3. .net创建并安装windows服务案例

    1. 创建windows服务[引用博文]: 1. 将这个服务程序切换到设计视图2. 右击设计视图选择“添加安装程序”3. 切换到刚被添加的ProjectInstaller的设计视图4. 设置servi ...

  4. RMAN duplicate from active 时遭遇 ORA-17627 ORA-12154

    最近在从活动数据库进行异机克隆时碰到了ORA-17629,ORA-17627,ORA-12154的错误,起初以为是一个Bug呢.Oracle Bug着实太多了,已经成了习惯性思维了.汗!错误提示是无法 ...

  5. Oracle 10g的空间管理

    一.表空间(包含表.字段.索引) 1.定义:表空间是一个逻辑概念,实质是组织数据文件的一种途径. 2.创建表空间 --创建表空间 create tablespace myspace datafile ...

  6. C#自动选择出系统中最合适的IP地址

    写这个是因为很长时间以来,碰到过很多次这个问题,但都没当回事,这次又碰到了这个老问题,无奈百度了一圈儿未果,身边又没有大牛可以请教,就自己先“总结”了一套方法,一来给自己记录,二来如果碰巧能有朋友看到 ...

  7. hdu4414(DFS 找十字架数量)

    Problem Description The Nazca Lines are a series of ancient geoglyphs located in the Nazca Desert in ...

  8. 适合编写代码的字体 Source Code Pro

    今天看到博客园一篇文章,介绍了一种出身自 Adobe 的适合编码的字体,等宽,支持ClearType等,试用一下吧 项目地址:https://github.com/adobe/source-code- ...

  9. 4月13号的web标准化交流化-开端

    这是实习工作的开始,也是正式踏入北京之后去参加的第一个活动.也算是想着法的去融入这个圈子. 这两个分享都是基于nodejs的.nodejs从11年开始就开始红火.但是真正nodejs能用来干什么? 我 ...

  10. MVC几种传值方式

    一,Model public class Course { public int Id { get; set; } public string Name { get; set; } } public ...