之前的代码中关闭了 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. NET Socket服务编程

    smark https://github.com/IKende/ .NET Socket服务编程之-高效连接接入编 在.NET上编写网络服务深入都有2,3年了,而这些时间时如何在.NET里实现网络服务 ...

  2. windows 7 telnet 开启关闭

    win7运行telnet提示:'telnet' 不是内部或外部命令,也不是可运行的程序或批处理文件 原因:win7默认没有打开此功能 解决方案:控制面板->程序和功能->打开或关闭wind ...

  3. jQueryRotate 转盘抽奖代码实现

    代码如下: 例子兼容IE6,7,8 以及高版本浏览器,如有bug请回复! 1.html结构 <!doctype html> <html lang="en"> ...

  4. 【转】android 欢迎界面翻页成效,仿微信第一次登陆介绍翻页界面

    android 欢迎界面翻页效果,仿微信第一次登陆介绍翻页界面 本实例做的相对比较简单主要是对翻页控件的使用,有时候想要做一些功能是主要是先了解下是否有现成的控件可以使用,做起来比较简单不用费太大的劲 ...

  5. Android--扫描二维码

    http://www.cnblogs.com/keyindex/archive/2011/06/08/2074900.html

  6. javaFile循环列出指定目录下的所有文件(源代码)

    package javatest.basic22; import java.io.File; import java.io.IOException; public class FileTest { p ...

  7. JavaScript插件——弹出框

    (JavaScript插件——弹出框) 前言 阅读之前您也可以到Bootstrap3.0入门学习系列导航中进行查看http://www.cnblogs.com/aehyok/p/3404867.htm ...

  8. WebLogic使用SSH架构部署遇到org.hibernate.hql.internal.ast.HqlTok

    其实这个问题在以前就遇到过,当时解决了,但今天在部署一个测试轻应用的时候一直没有想起来,特此记录一下. 这个问题出现在使用WebLogic(我使用的是10.3.5版本)发布SSH架构的应用.在操作数据 ...

  9. JS之For---in 语句

    下面说一下for… in语句.可直接把下面的代码复制到浏览器的控制台或Node环境下去执行. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ //用来快速迭代对象. var o ...

  10. 关于UITextfield弹出键盘解决方案

    解决的问题:当你点击一个UITextfield时,不想让其弹出键盘,如果你觉得不就是取消其第一响应者嘛,resignRespond一下不就行了嘛,确实,如果你只是在其编辑完成后让其键盘消失,那这个就够 ...