我正在使用SocketChannel与远程服务器通信。我使用socketChannel.write()发送数据,没有错误和异常,但是,服务器日志表明没有收到数据; client tcp traffic monitor还显示ByteBuffer中的字符串消息未发送。
有人能给我一个暗示为什么会这样吗?谢谢!
public class Client implements Runnable {
SocketChannel socketChannel;
Selector selector;
SelectionKey key;
ByteBuffer inbuf, outbuf;
int id;
@Override
public void run() {
try {
// prepare inbuf and outbuf
inbuf = ByteBuffer.allocate(10000);
outbuf = ByteBuffer.allocate(10000);
// prepare a socket channel for communication
socketChannel = SocketChannel.open();
socketChannel.connect(new InetSocketAddress("<remote server ip>", ));
selector = Selector.open();
socketChannel.configureBlocking(false);
key = socketChannel.register(selector, SelectionKey.OP_READ
| SelectionKey.OP_WRITE);
while (selector.select() > 0) {
if (key.isReadable()) {
// read from channel when server sends data
read();
}
if (key.isWritable()) {
// write
Random r = new Random(500);
write("b", r.nextInt(), r.nextInt());
for (int i = 0; i < 10; i++) {
// write a message to server after 1 second
Thread.sleep(1000);
write("m", r.nextInt(), r.nextInt());
}
write("e", r.nextInt(), r.nextInt());
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void write(String action, int x, int y) throws IOException {
String msg = String.format("%s:%d:%d:%d", action, id, x, y);
int r=outbuf.remaining();
outbuf.put(msg.getBytes());
int rBytes = outbuf.remaining();
boolean connected = socketChannel.isConnected();
Socket sock = socketChannel.socket();
if (connected && sock.isConnected() && !sock.isOutputShutdown())
>>>>>>>>>> socketChannel.write(outbuf);
else
System.out.println("Connection broken!");
System.out.printf("Client %d told server:%s\n", id, msg);
//outbuf.clear();
}
... //read omitted here
答案 0 :(得分:6)
将内容放入缓冲区或读取内容后,您必须翻转缓冲区以写入或从中获取数据。检查Buffer类中的flip()
方法。文档说
翻转此缓冲区。限制设置为当前位置,然后位置设置为零。如果定义了标记,则将其丢弃。 在一系列通道读取或放置操作之后,调用此方法以准备一系列通道写入或相对获取操作。
因此在put之后添加一个buffer.flip()应该可以解决问题:)