Java Tcp套接字:如何在客户端检测服务器不再需要接收数据

Java Tcp socket: how to detect on client that no more data needs to be received by server?

本文关键字:不再 服务器 数据 检测 客户端 套接字 Tcp Java      更新时间:2023-10-16

我正在将java套接字上的byte[]发送到c++服务器。客户端不知道要提前发送多少数据。是否有其他方法可以在客户端检测所有数据是否已发送,以便套接字可以断开连接而不会在服务器端丢失数据?目前,我正在使用Thread.sleep(1000)在接收到所有数据之前不断开连接,但是否有更好的方法来做到这一点?

server.cpp:

do{
 memset(chunk ,0 , 4096);
 n = recv(sock , chunk , 4096 , 0);
 myFile.write(chunk, n);
} while (n>0);

client.java

while(isSending){
 try {
  DataOutputStream out = new DataOutputStream(socket.getOutputStream());
  data = getDataFromQueue();
  out.write(data,0,data.length);
  out.flush();
 } catch (IOException e) {
  // TODO Auto-generated catch block
 e.printStackTrace();
 }
}
//how to wait here until all data was received?
try {
  socket.close();
} catch (IOException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
}

TCP连接为全双工。有两个独立的字节流,每个方向一个。您可以关闭连接的写部分,这称为half-close。当前在套接字发送缓冲区中的任何数据都将被发送,然后是TCP正常的连接终止顺序。服务器将读取0字节,然后在对recv的调用中读取0字节,这表示客户端关机。

我不是Java专家,但快速搜索告诉我shutdownOutput()函数是您在Java中使用的关闭发送一半连接的功能。

http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html shutdownOutput ()

在发送完最后一个字节后关闭客户端的套接字。客户端将确保在发送关闭连接的fin包之前发送所有打算发送给服务器的数据。当远程方关闭套接字时,将在客户端抛出异常。如果我的Java套接字内存正确地为我服务,则在接收到最后一个字节之前不应该抛出此异常。这里有一个基本的代码示例:http://hepunx.rl.ac.uk/~adye/javatutorial/networking/sockets/readingWriting.html

另一种方法是创建自己的头,首先发送,其中包含将要发送的字节数

是否有其他方法可以在客户端检测所有数据已发送,以便套接字可以断开连接而不会在服务器端丢失数据?

如果您关闭套接字就会丢失数据的假设是不正确的。如果正常关闭套接字,TCP将确保所有挂起的数据都已交付。把插座关上。不需要睡觉

如果你想知道对等端是否收到了所有的数据,关闭套接字输出,并让对等端在关闭套接字之前读取流结束时发送一个应用协议确认。在发送方,在关闭后和关闭前阅读此确认。如果你得到它,一切都很好。