上篇文章介绍了Socket和ServerSocket简单使用和源码,服务器端会对每个客户端请求创建一个线程,为使服务器端能同时处理多个客户端请求,可以采用多线程的方式。本文仅对实例进行简单记录,如下。

服务器端

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class MultiJabberServer { static final int PORT = 8080; public static void main(String[] args) throws IOException{
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("Server Started");
try {
while(true) {
Socket socket = serverSocket.accept();
try {
new ServeOneJabber(socket);
} catch (IOException e) {
// If it fails, close the socket,
// otherwise the thread will close it:
socket.close();
}
}
} finally {
serverSocket.close();
}
}
}

while循环获取连接,并构造ServerOneJabber,启动线程处理客户端交互。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket; public class ServeOneJabber extends Thread{ private Socket socket; private BufferedReader in; private PrintWriter out; public ServeOneJabber(Socket socket) throws IOException{
this.socket = socket;
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())),true);
start();
} public void run() {
try {
while (true) {
String str = in.readLine();
if ("END".equals(str)) {
break;
}
System.out.println("Echoing: " + str);
out.println("Got: " + str);
}
System.out.println(socket + ", seesion closing....");
} catch (IOException e) {
System.out.println(e.getMessage());
} finally {
try {
socket.close();
} catch (Exception e2) {
System.out.println("Socket not closed");
}
}
}
}

原理与上篇文章一样,获取输入输出流,对请求信息进行处理和响应。

客户端

import java.io.IOException;
import java.net.InetAddress; public class MultiJabberClient { static final int MAX_THREADS = 40; public static void main(String[] args) throws IOException, InterruptedException{
InetAddress addr = InetAddress.getByName(null);
for(int i = 0; i < MAX_THREADS; i++) {
new JabberClientThread(addr);
Thread.sleep(100);
}
// while(true) {
// if(JabberClientThread.threadCount() < MAX_THREADS) {
// new JabberClientThread(addr);
// }
// Thread.sleep(100);
// }
}
}

构造线程JabberClientThread,构建Socket,与服务器端连接。

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket; public class JabberClientThread extends Thread{
private Socket socket;
private BufferedReader in;
private PrintWriter out;
private static int counter = 0;
private int id = counter++;
private static int threadCount = 0; public static int threadCount() {
return threadCount;
} public JabberClientThread(InetAddress addr){
System.out.println("Making client " + id);
threadCount++;
try {
socket = new Socket(addr, MultiJabberServer.PORT);
} catch (IOException e) {
// If the creation of the socket fails,
// nothing needs to be cleaned up.
System.out.println("Socket failed");
return;
}
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream())), true);
start();
} catch (IOException e) {
// The socket should be closed on any
// failures other than the socket
// constructor:
try {
socket.close();
} catch (IOException e2) {
System.err.println("Socket not closed");
} }
} public void run() {
try {
for(int i = 0; i < 5; i++) {
out.println("Client " + id + ":" + i);
String str = in.readLine();
System.out.println(str);
}
out.println("END");
} catch (IOException e) {
System.err.println("IO Exception");
} finally {
try {
socket.close();
} catch (IOException e2) {
System.err.println("Socket not closed");
}
threadCount--;
}
}
}

其中包含成员属性id和threadCount,每创建一个线程,id递增(采用类成员控制);threadCount作为线程数量的记录,线程创建时加一,结束时减一。

运行结果如下

服务器端:

Server Started
Echoing: Client 0:0
Echoing: Client 0:1
Echoing: Client 0:2
Echoing: Client 0:3
Echoing: Client 0:4
Socket[addr=/127.0.0.1,port=42998,localport=8080], seesion closing....
Echoing: Client 1:0
Echoing: Client 1:1
Echoing: Client 1:2
Echoing: Client 1:3
Echoing: Client 1:4
Socket[addr=/127.0.0.1,port=43000,localport=8080], seesion closing....
......
Echoing: Client 39:0
Echoing: Client 39:1
Echoing: Client 39:2
Echoing: Client 39:3
Echoing: Client 39:4
Socket[addr=/127.0.0.1,port=43076,localport=8080], seesion closing....

客户端:

Making client 0
Got: Client 0:0
Got: Client 0:1
Got: Client 0:2
Got: Client 0:3
Got: Client 0:4
Making client 1
Got: Client 1:0
Got: Client 1:1
Got: Client 1:2
Got: Client 1:3
Got: Client 1:4
.....
Making client 39
Got: Client 39:0
Got: Client 39:1
Got: Client 39:2
Got: Client 39:3
Got: Client 39:4

JAVA I/O(五)多线程网络Socket和ServerSocket的更多相关文章

  1. Java:基于TCP协议网络socket编程(实现C/S通信)

    目录 一.前言:TCP原理简介 二.Socket编程通信 三.TCP服务器端(具体代码) 四.TCP客户端(具体代码) 五.通信效果演示 六."创意"机器人:价值一个亿的AI核心代 ...

  2. JAVA I/O(四)网络Socket和ServerSocket

    <Thinking in Enterprise Java>中第一章描述了用Socket和Channel的网络编程,核心即为Socket和Channel,本文简单讲述Socket的应用. S ...

  3. java多线程实现TCP网络Socket编程(C/S通信)

    目录 开篇必知必会 一.多线程技术 二.实现多线程接收 1.单线程版本 2.多线程版本 三.多线程与进程的关系 四.客户端界面完整代码 五.多线程通信对比 最后 开篇必知必会 在前一篇<Java ...

  4. 网络开发Socket和ServerSocket

    已经发表个人公众号 Socket和ServerSocket Socket为"孔"或"插座",创建Socket,打开连接Socket的输入或输出流,对Socket ...

  5. java socket 多线程网络传输多个文件

    http://blog.csdn.net/njchenyi/article/details/9072845 java socket 多线程网络传输多个文件 2013-06-10 21:26 3596人 ...

  6. Java实验报告五:Java网络编程及安全

    Java实验报告五:Java网络编程及安全                                                                               ...

  7. Java基础知识➣网络Socket(六)

    概述 网络编程是指编写运行在多个设备(计算机)的程序,这些设备都通过网络连接起来. java.net 包中提供了两种常见的网络协议的支持: TCP:TCP 是传输控制协议的缩写,它保障了两个应用程序之 ...

  8. 20155205《Java程序设计》实验五(网络编程与安全)实验报告

    20155205 <Java程序设计>实验五(网络编程与安全)实验报告 一.实验内容及步骤 (一) 两人一组结对编程 参考http://www.cnblogs.com/rocedu/p/6 ...

  9. 20165230 《Java程序设计》实验五《网络编程与安全》实验报告

    20165230 <Java程序设计>实验五<网络编程与安全>实验报告 一.实验报告封面 课程:Java程序设计 班级:1652班 姓名:田坤烨 学号:20165230 成绩: ...

随机推荐

  1. Qt 事件系统浅析 (用 Windows API 描述,分析了QCoreApplication::exec()和QEventLoop::exec的源码)(比起新号槽,事件机制是更高级的抽象,拥有更多特性,比如 accept/ignore,filter,还是实现状态机等高级 API 的基础)

    事件系统在 Qt 中扮演了十分重要的角色,不仅 GUI 的方方面面需要使用到事件系统,Signals/Slots 技术也离不开事件系统(多线程间).我们本文中暂且不描述 GUI 中的一些特殊情况,来说 ...

  2. [py]python中的特殊类class type和类的两面性图解

    生活中的模具 生活中 编程 万物都从无到有, 起于烟尘 () 生产原料,铁 object 车床-生产各类模具 元类即metaclass,对应python的class type 模具-生产各类实在的物品 ...

  3. dialog提交表单

    <div id="dialog" title="添加客户"> <!--表单提交--> <form id="dialogF ...

  4. AI-Tank

    编程,就是编写人生,你的思维越好,就的生活就会充满乐趣,不多说了,下面来讲一个游戏. 讲游戏的开始,要说一点,游戏可以玩,不能沉溺.不然人的一生就会沦陷进去. 下面讲一个使用的代码游戏. 在玩游戏的时 ...

  5. jquery控制css的display属性(显示与隐藏)

    jquery控制div的显示与隐藏,很方便的. 例如: $("#id").show()表示display:block, $("#id").hide()表示dis ...

  6. 翻译[RFC6238] TOTP: Time-Based One-Time Password Algorithm

    在闲暇时间做了一个TOTP相关的开源项目,在项目初步完成之余,我尝试对[RFC6238]文档进行了翻译,供大家参考与查阅,若有不妥之处,还望各位前辈海涵斧正. [RFC6238] : Time-Bas ...

  7. stdcall cdecl

    一.stdcall windows API采用的都是这种方式 1.参数入栈由右向左 2.栈平衡由被调用者处理 二.cdcel C语言库采用的都是这种方式 1.参数入栈由右向左 2.栈平衡由调用者处理 ...

  8. MFC工具栏的创建、设计与使用实例

    本文通过实例说明MFC工具栏的创建.设计和使用方法,包括三个demo.       demo1:创建一个工具栏 C++代码 //摘抄自MSDN demo1 (创建一个工具栏) 1.Create a t ...

  9. Manacher 计算最长回文串

    转自 http://blog.sina.com.cn/s/blog_3fe961ae0101iwc2.html 寻找字符串中的回文,有特定的算法来解决,也是本文的主题:Manacher算法,其时间复杂 ...

  10. 线段树(I tree)

    Codeforces Round #254 (Div. 2)E题这题说的是给了一个一段连续的区间每个区间有一种颜色然后一个彩笔从L画到R每个区间的颜色都发生了 改变然后 在L和R这部分区间里所用的颜色 ...