如何获取Socket的SendBuffer中的字节数?

时间:2011-12-03 18:37:57

标签: java sockets tcp protocol-buffers

我有一个网络应用程序,可能无法访问服务器。客户端通过TCP连接每隔30秒将字符串ping\n的空闲时间发送到服务器,以便服务器可以查看客户端是否在线。我的服务器根本没有响应。如果连接中断并且客户端继续发送“ping”消息,则包可以由操作系统存储在缓冲区中,直到服务器获得包。如果服务器重新联机,则服务器可能会立即获得数十个ping包。是否有可能获得缓冲区的字节数?

编辑: 如何获取客户端必须发送的计数字节?

2 个答案:

答案 0 :(得分:0)

如果您在询问是否可以检测到,在调用网络套接字上的读取之前,有多少字节可供读取,简短答案为否。您只能检测是否有任何字节可供读取但不能检测字节数。客户端也可能将字节写入其内核但被服务器的完整缓冲区阻止,因此服务器本身可能不知道有多少字节可供读取。此外,从客户端来看,无法确定客户端已写入多少数据但服务器未使用该数据。

数据在客户端和服务器端都是缓冲的,但Java中无法查看这些缓冲区中有多少字节。你可能能够在C中使用一些非常具体的内核调用来获取它,但它非常不可移植。

  • 要考虑的一件事是使用Socket.setKeepAlive(true),它将使用TCP机制来保持套接字处于活动状态。我不确定服务器端有多可靠,但是当客户端消失后套接字超时时,应该从读取中得到-1。
  • 另一种方法是为每个ping建立一个单独的TCP连接。如果这太贵了,那么你可以在一定数量的ping尝试后重新连接。
  • 要考虑的第三件事是从客户端发送UDP数据包,这些数据包不会被缓冲并且价格便宜得多。你应该更频繁地发送,因为没有重试。
  • 服务器还可以发回某种响应,以便客户端知道客户端知道套接字仍然是好的。如果没有得到响应,它可以重新连接。

答案 1 :(得分:-1)

  

是否可以获得该缓冲区的字节数?

如果应用程序缓冲区足够大,那么成功的下一个read()会将其作为返回值。但那对你有什么好处呢?您仍然必须阅读所有数据并进行处理。问题似乎毫无意义。