Deplyment environment:我在Windows 10 OS上使用JAVA创建了一个TCP服务器。我的TCP客户端程序是用VC ++编写的,在Windows 7操作系统上运行(我对这部分代码没有任何控制权,对我来说这是一个黑盒子)。
我的TCP服务器代码是这样的:
Socket s = ss.accept();
s.setReceiveBufferSize(2000);
s.setSendBufferSize(2000);
s.setTcpNoDelay(true);
s.setKeepAlive(true);
new TcpConnectionHandler(s,this.packetHandler);
以下是TCP连接处理程序片段:
InputStream incomingPacketBuffer = this.clientSocket.getInputStream();
OutputStream outgoingPacketBuffer = this.clientSocket.getOutputStream();
int bufferLen=0;
byte inBuffer[] = new byte[this.clientSocket.getReceiveBufferSize()];
byte outBuffer[] = new byte[this.clientSocket.getSendBufferSize()];
while(this.clientSocket.isConnected())
{
bufferLen = incomingPacketBuffer.read(inBuffer);
if(bufferLen>0)
{
outBuffer = (byte[]) this.packetHandlerModule.invoke(this.packetHandler,Arrays.copyOf(inBuffer, bufferLen));
}
if(outBuffer != null)
{
if(this.clientSocket.isConnected())
{
outgoingPacketBuffer.write(outBuffer);
outgoingPacketBuffer.flush();
}
}
}
this.clientSocket.close();
通信是基于分组的,协议/解析由packetHandler
处理。
我试过的另外两个变种:
inputStream.available
方法之前我使用了read
。我面临的问题:
大多数情况下,TCP服务器会在一秒钟内回复传入的数据包。如果服务器在一些空闲时间之后收到数据包,则服务器不会回复数据包。有时即使正在进行活动通信,也不会传输回复。其次,即使客户端套接字关闭连接,isConnected
函数也会返回true。
调试尝试:
setKeepAlive
设置为true(从服务器发送数据包时没有问题)。问题很简单:“有时,即使有传入的数据包,TCP读取呼叫也会被长时间阻止。当按下Ctrl + C时,它们会被处理。”
PS:我刚开始在stackexchange上发布查询,所以如果在制定查询方面存在任何问题,请告诉我。
PPS:很抱歉这么长的帖子。
UPDATE
有些事情需要考虑;
byte[]
的大小在2K左右并不重要,你也可以选择一个值。所以总之我会尝试。
Socket s = ss.accept();
s.setTcpNoDelay(true);
s.setKeepAlive(true);
new TcpConnectionHandler(s,this.packetHandler);
和
try {
InputStream in = this.clientSocket.getInputStream();
OutputStream out = this.clientSocket.getOutputStream();
int bufferLen = 0;
byte[] buffer = new byte[2048];
while ((bufferLen = in.read(buffer)) > 0) {
out.write(buffer, 0, bufferLen); // not buffered so no need to flush
}
} finally {
this.clientSocket.close();
}
有时,即使有传入的数据包,TCP读取呼叫也会被长时间阻止。
编写一个测试Java客户端,看看这不是由于Java中的行为造成的。