最近在做 Socket开发,为了方便本地调试,特地写一个简单的 socket服务端,做回响(接收到什么回什么),并且用于客户端心跳测试。
EchoSocketServer .java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
/**
* 回响 Socket服务器
*/
public class EchoSocketServer {
private static final int PORT = 8888;
public static void main(String[] args) {
EchoSocketServer server = new EchoSocketServer(PORT);
}
/**
* 线程池
*/
private ExecutorService executorService = null;
/**
* 服务
*/
private ServerSocket serverSocket = null;
/**
* 客户端列表
*/
private List<Socket> socketList = new ArrayList<>();
private EchoSocketServer(int port) {
try {
// 创建服务器 socket
serverSocket = new ServerSocket(port);
// 初始化线程池
executorService = Executors.newCachedThreadPool();
System.out.println("服务启动完成,等待客户端连接...");
Socket client = null;
while (true) {
client = serverSocket.accept();
socketList.add(client);
executorService.execute(new Service(client));
}
} catch (IOException e) {
e.printStackTrace();
}
// TODO
// socketList 管理
}
private static class Service implements Runnable {
/**
* 20 秒超时服务器主动断开
*/
private static final long TIMEOUT_MILLISECOND = 20000;
private Socket socket;
private boolean isConnect;
private long lastReceiveTime = System.currentTimeMillis();
public Service(Socket socket) {
this.socket = socket;
this.isConnect = true;
System.out.println(socket.getInetAddress() + ":" + socket.getPort() + " <连接>");
}
@Override
public void run() {
while (isConnect) {
// 超时
if (System.currentTimeMillis() - lastReceiveTime > TIMEOUT_MILLISECOND) {
stopService();
} else {
try {
// 默认接收 1024字节
byte[] bytes = new byte[1024];
InputStream in = socket.getInputStream();
if (in.available() > 0) {
lastReceiveTime = System.currentTimeMillis();
int len = in.read(bytes);
String content = new String(bytes);
System.out.println(socket.getInetAddress() + ":" + socket.getPort() + " " + content);
// 回响
OutputStream os = socket.getOutputStream();
os.write(bytes);
os.flush();
} else {
Thread.sleep(10);
}
} catch (Exception e) {
e.printStackTrace();
stopService();
}
}
}
}
/**
* 断开客户端
*/
private void stopService() {
isConnect = false;
System.out.println(socket.getInetAddress() + ":" + socket.getPort() + " <断开>");
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}