这里的问题是我可以看到数据正被写入套接字,但它并不总是被发送。
这是一个代码片段
ByteBuffer writeBuffer = ByteBuffer.allocate(8192);
writeBuffer.clear();
writeBuffer.put("heartbeat".getBytes());
writeBuffer.flip();
LOG.debug("is connected: " + socketChannel.isConnected());
int bytesWritten = 0;
if (key.isWritable()) {
while (writeBuffer.hasRemaining()) {
bytesWritten += socketChannel.write(writeBuffer);
}
}
我使用TCPMon来查看实际数据是否写入套接字 - 它的作用是什么。
但是使用WireShark(另一种网络监控工具)我看不到数据包通过网卡。
任何帮助将不胜感激
答案 0 :(得分:5)
无论如何你的代码都是错误的。如果写入返回零,则套接字发送缓冲区已满,因此您应该注册OP_WRITE并返回到选择循环,而不是浪费时间旋转直到再次有空间。您现有的技术使其他服务渠道匮乏,浪费CPU周期。
此外,此时测试isConnected()
是徒劳的。它是。你连接了它。该方法告诉您套接字的状态,而不是连接。
答案 1 :(得分:-1)
尝试如下
/**
* @param socketChannel
* @param buf
* @return no. of bytes written to the socket
* @throws IOException
*/
public static int writeByteBuffer(SocketChannel socketChannel, ByteBuffer buf) throws IOException {
boolean blocking = socketChannel.isBlocking();
Selector selector = Selector.open();
int totalWritten = 0;
try {
socketChannel.configureBlocking(false);
// pass SelectionKey.OP_READ | SelectionKey.OP_WRITE for read and
// write
socketChannel.register(selector, SelectionKey.OP_WRITE);
selector.select();
Set<SelectionKey> selectedKeys = selector.selectedKeys();
Iterator<SelectionKey> keyIterator = selectedKeys.iterator();
outerOfWriting: while (keyIterator.hasNext()) {
SelectionKey key = keyIterator.next();
boolean writable = key.isWritable();
if (writable) {
SocketChannel channel = (SocketChannel) key.channel();
boolean hasRemaining = false;
while (hasRemaining = buf.hasRemaining()) {
int written = channel.write(buf);
totalWritten += written;
if (written == 0) {
selector.select();
selectedKeys = selector.selectedKeys();
keyIterator = selectedKeys.iterator();
continue outerOfWriting;
}
}
if (!hasRemaining) {
key.cancel();
break;
}
}
}
} finally {
try {
selector.close();
socketChannel.configureBlocking(blocking);
} catch (IOException e) {
e.printStackTrace();
}
}
return totalWritten;
}
public static void main(String[] args) {
try {
ByteBuffer writeBuffer = ByteBuffer.allocate(8192);
writeBuffer.clear();
writeBuffer.put("heartbeat".getBytes());
writeBuffer.flip();
SocketChannel socketChannel = null;//initialize
writeByteBuffer(socketChannel, writeBuffer);
} catch (IOException e) {
e.printStackTrace();
}
}