嘿伙计们,我正在开发一个服务器程序,该程序可以很好地扩展并为数千个客户提供服务。问题是,我觉得Apache MINA太重了,所以我决定不使用它而是写了我自己的客户端监听器。我从来没有真正用Java执行异步套接字操作(C#使得这么简单,但我真的更喜欢用Java编写这个项目,因为除了套接字读取之外,我对它更熟悉),所以试着理解如何使用它正确的线程池对我来说很难。我使用Apache MINA文档来了解应该如何完成任务。我有两个问题:
以下是我启动听众的方式:
ClientListener cl = new ClientListener(1234);
cl.init();
new Thread(cl).start();
以下是ClientListener的相关代码:
private static final int THREADS = Runtime.getRuntime().availableProcessors() + 1;
private ServerSocket socket;
private ExecutorService threadPool;
private int port;
public ClientListener(int port) {
this.port = port;
threadPool = Executors.newFixedThreadPool(THREADS);
}
public void init() {
try {
socket = new ServerSocket(port);
} catch (IOException ex) {
}
}
public void run() {
while (true) {
try {
ClientSession s = new ClientSession(socket.accept());
threadPool.execute(s);
} catch (IOException ex) {
}
}
}
ClientSession相关代码:
private Socket socket;
private byte[] buffer;
private boolean isHeader;
public ClientSession(Socket socket) {
this.socket = socket;
this.buffer = new byte[4];
this.isHeader = true;
}
public void run() {
InputStream in;
try {
in = socket.getInputStream();
out = socket.getOutputStream();
} catch (IOException ex) {
return;
}
while (!socket.isClosed()) {
try {
int read = in.read(buffer);
if (read == -1)
break;
receive(read);
} catch (IOException ex) {
break;
}
}
}
private void receive(int readBytes) {
if (isHeader) {
if (readBytes >= 4) {
buffer = new byte[getPacketLength(buffer)];
isHeader = false;
} else {
System.out.println("Not enough data received from client " + socket.getInetAddress() + " to decode packet.");
}
} else {
if (readBytes >= buffer.length) {
processMessage(new LittleEndianByteArrayReader(decryptData(buffer)), this);
buffer = new byte[4];
isHeader = true;
} else {
System.out.println("Not enough data received from client " + socket.getInetAddress() + " to decode packet (needed " + buffer.length + ", received " + readBytes + ").");
}
}
}
您不需要知道getPacketLength,processMessage,decryptData和LittleEndianByteArrayReader类的代码,但我很确定这些方法/类的用途是显而易见的。
答案 0 :(得分:0)
阻止IO方案中的线程数必须通过客户端数量和每个客户端连接打开的时间来计算。 每个用户的每个连接都需要在线程上。
只有三个线程,用户只需打开三个TCP连接并且不向服务器发送任何数据,就可以直接阻止服务器直到连接超时。
答案 1 :(得分:0)
没关系。我意识到Apache MINA实际上使用的是NIO,这就是为什么我感到困惑。它确实只需要一个线程来使用选择器来处理请求。感谢您的所有答案,对此感到抱歉!