我正在尝试使用NIO和选择器在Java中编写一个简单的客户端/服务器。该服务器非常简单,它是随处可见的最典型的实现。这是服务器的代码(请看start()
方法):
public final class MyServer {
private int port;
private String address;
public MyServer(String address, int port) {
this.address = address;
this.port = port;
}
public void start() throws IOException {
try {
Selector selector = Selector.open();
ServerSocketChannel socket = ServerSocketChannel.open();
InetSocketAddress addr = new InetSocketAddress(address, port);
socket.bind(addr);
socket.configureBlocking(false);
boolean isAlive = true;
SelectionKey selectKy = socket.register(selector, SelectionKey.OP_ACCEPT, null);
while (isAlive) {
selector.select();
Set<SelectionKey> keysList = selector.selectedKeys();
Iterator<SelectionKey> keys = keysList.iterator();
while (keys.hasNext()) {
SelectionKey theKey = keys.next();
if (theKey.isAcceptable()) {
SocketChannel clientSocket = socket.accept();
clientSocket.configureBlocking(false);
clientSocket.register(selector, SelectionKey.OP_READ);
}
if (theKey.isReadable()) {
SocketChannel clientSocket = (SocketChannel) theKey.channel();
ByteBuffer buffer = ByteBuffer.allocate(9000);
clientSocket.read(buffer);
String result = new String(buffer.array()).trim();
System.out.println(" > SERVER: Request from " + clientSocket.getLocalAddress() + " [ toValidate = " + result + " ], sending tokens...");
//Now I send to the client a list
buffer.flip();
for (int i = 0; i < 5; ++i)
buffer.put((byte) getRandom(1, 10));
clientSocket.write(buffer);
buffer.clear();
System.out.println(" > SERVER: Response successfully sent");
}
keys.remove();
}
}
} catch (Exception e) {
System.out.println("[ SERVER ALERT: " + e.getMessage() + " ]");
}
}
}
如您所见,代码很基本。在if (theKey.isReadable())
内部,我尝试从客户端读取一个小字符串,将其打印到控制台,然后翻转缓冲区,然后将一些数据发送回客户端。
在这里,我们的客户不幸遇到了一个我找不到的问题:
public void something() throws IOException, InterruptedException {
ByteBuffer buffer = ByteBuffer.allocate(9000);
//Note that mRequests is a List of strings
try (SocketChannel client = SocketChannel.open(new InetSocketAddress(authIPAddr, authPort));) {
//For each transaction in mRequests, get the tokens from the server and verify them
for (String s : mRequests) {
//Write the string to the buffer and send the string
buffer.put(s.getBytes());
client.write(buffer);
buffer.rewind();
//Get response from the server
client.read(buffer);
buffer.clear();
Thread.sleep(1000);
}
}
}
问题就在这里:
buffer.put(s.getBytes());
client.write(buffer);
buffer.rewind();
我可以说问题出在那儿,因为服务器应该打印
SERVER:来自/127.0.0.1:2323的请求[toValidate = {some_value}],正在发送 令牌...
但它打印
SERVER:来自/127.0.0.1:2323的请求[toValidate =],正在发送 令牌...
,据此我猜数据没有发送到服务器。我该怎么解决?