Java 网络通信 — 使用线程池搭建TCP BIO通信服务器
程序员文章站
2022-06-06 08:02:18
...
服务端使用一个线程池大小为5个线程去监听socket
package top.yuyufeng.test;
import org.junit.Test;
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;
/**
* 服务端
* created by yuyufeng on 2017/8/18.
*/
public class TestTcpServer {
private static ExecutorService executor = Executors.newFixedThreadPool(5);
private static AtomicInteger count = new AtomicInteger();
// 服务端
public static void main(String[] args) throws ClassNotFoundException {
ServerSocket ss = null;
Socket s = null;
try {
ss = new ServerSocket(8989);
System.out.println("服务端已经启动...");
while (true) {
int id = count.getAndAdd(1);
executor.execute(new ServerTask(id, ss.accept()));
System.out.println("执行一次响应.." + id);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
if (ss != null) {
try {
ss.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
}
}
}
class ServerTask implements Runnable {
private Integer id;//任务标记
private Socket socket;
public ServerTask(Integer id, Socket socket) {
this.id = id;
this.socket = socket;
}
public void run() {
ObjectOutputStream os = null;
ObjectInputStream is = null;
try {
is = new ObjectInputStream(socket.getInputStream());
//读取第一部分数据
TransportObject transportObject = (TransportObject) is.readObject();
System.out.println(transportObject.toString() + "任务标记:" + id);
//读取第二部分数据
transportObject = (TransportObject) is.readObject();
System.out.println(transportObject.toString() + "任务标记:" + id);
os = new ObjectOutputStream(socket.getOutputStream());
os.writeObject(new TransportObject(1, "我是客户端!"));
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} finally {
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
客户端启动6个线程去请求服务器
package top.yuyufeng.test;
import org.junit.Test;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Random;
/**
* 客户端
* created by yuyufeng on 2017/8/18.
*/
public class TestTcpClient {
public static void main(String[] args) throws ClassNotFoundException, InterruptedException {
// send();
for (int i = 0; i < 6; i++) {
new Thread() {
@Override
public void run() {
while (true) {
try {
send();
Thread.sleep(100);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}.start();
}
}
private static void send() throws ClassNotFoundException {
Socket socket = null;
ObjectOutputStream os = null;
ObjectInputStream is = null;
try {
socket = new Socket(InetAddress.getByName("127.0.0.1"), 8989);
os = new ObjectOutputStream(socket.getOutputStream());
//发送两次数据
os.writeObject(new TransportObject(2, "我是客户端1!"));
os.writeObject(new TransportObject(3, "我是客户端2!"));
// shutdownOutput():执行此方法,显示的告诉服务端发送完毕
socket.shutdownOutput();
//阻塞等待服务器响应
is = new ObjectInputStream(socket.getInputStream());
TransportObject transportObject = (TransportObject) is.readObject();
System.out.println(transportObject.toString());
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (os != null) {
try {
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
执行结果(部分)
服务端已经启动...
执行一次响应..0
执行一次响应..1
执行一次响应..2
执行一次响应..3
执行一次响应..4
执行一次响应..5
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:3
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:2
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:3
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:2
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:4
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:4
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:0
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:0
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:1
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:1
执行一次响应..6
执行一次响应..7
执行一次响应..8
执行一次响应..9
执行一次响应..10
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:5
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:8
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:5
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:8
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:7
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:6
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:7
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:6
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:9
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:9
执行一次响应..11
执行一次响应..12
执行一次响应..13
执行一次响应..14
执行一次响应..15
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:10
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:11
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:12
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:45 CST 2017}任务标记:10
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:11
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:12
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:13
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:13
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:14
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:14
执行一次响应..16
执行一次响应..17
执行一次响应..18
执行一次响应..19
执行一次响应..20
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:15
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:16
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:18
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:18
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:17
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:16
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:46 CST 2017}任务标记:15
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:17
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:19
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:19
执行一次响应..21
执行一次响应..22
执行一次响应..23
执行一次响应..24
执行一次响应..25
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:21
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:20
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:21
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:22
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:47 CST 2017}任务标记:20
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:22
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:23
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:23
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:24
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:24
执行一次响应..26
执行一次响应..27
执行一次响应..28
执行一次响应..29
执行一次响应..30
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:26
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:28
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:26
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:28
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:27
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:25
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:27
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:48 CST 2017}任务标记:25
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:29
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:29
执行一次响应..31
执行一次响应..32
执行一次响应..33
执行一次响应..34
执行一次响应..35
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:30
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:31
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:32
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:31
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:49 CST 2017}任务标记:30
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:32
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:33
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:33
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:34
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:34
执行一次响应..36
执行一次响应..37
执行一次响应..38
执行一次响应..39
执行一次响应..40
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:36
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:38
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:36
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:38
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:37
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:35
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:50 CST 2017}任务标记:35
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:37
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:39
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:39
执行一次响应..41
执行一次响应..42
执行一次响应..43
执行一次响应..44
执行一次响应..45
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:41
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:42
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:40
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:42
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:43
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:43
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:51 CST 2017}任务标记:40
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:41
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:44
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:44
执行一次响应..46
执行一次响应..47
执行一次响应..48
执行一次响应..49
执行一次响应..50
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:53 CST 2017}任务标记:46
TransportObject{id=2, content='我是客户端1!', date=Fri Aug 18 21:45:52 CST 2017}任务标记:45
TransportObject{id=3, content='我是客户端2!', date=Fri Aug 18 21:45:53 CST 2017}任务标记:46