2009-12-11 53 views
1

我有一个通过TCP进行通信的客户端/服务器程序(Windows,winsock2)。 客户端一次连接并发送数据到服务器(使用发送)8K。 服务器只读取数据(使用recv)。TCP发送/ recv错误报告

没有在套接字上进行特殊设置。

问题: 当通信期间发生了一些网络错误(例如电缆拉出),接收器没有得到由该时间成功发送的数据。 为了简化, 客户端发送了10个要发送的80K数据。 (所有发送都成功)。由于某些网络问题,第11次发送失败。在此之后不再发送任何数据。

问题是在接收端,并不是所有的80K数据都被接收到。它始终小于80K。

我希望发件人成功发送80K时,TCP将保证将大量数据传送到目标TCP(数据可能不会被应用程序接收,但它在目标TCP缓冲区中)。

我错过了什么?

感谢

编辑:

示例代码

服务器/接收器

/* create socket */ 
/* listen */ 
/* accept connection */ 
char recvbuf[8192]; 
do { 

    iResult = recv(ClientSocket, recvbuf, sizeof(recvbuf), 0); 
    if (iResult > 0) { 
     total += iResult; 
     printf("Total bytes received: %d\n", total); 
    } 
    else if (iResult == 0) { 
     printf("Connection is closing...\n"); 
     break; 
    } 
    else { 
     printf("recv failed: %d\n", WSAGetLastError()); 
     break; 
    } 

} while (iResult > 0); 

客户端/发件人:

/* create socket */ 
/* connect to server */ 
char sendbuf[8192]; 

do { 
    // Send an initial buffer 
    iResult = send(ConnectSocket, sendbuf, sizeof(sendbuf), 0); 
    if (iResult == SOCKET_ERROR) { 
     printf("send failed: %d\n", WSAGetLastError()); 
     break; 
    } 
    total += iResult; 
    printf("Total bytes Sent: %ld\n", total); 
} while(iResult > 0); 
//wait before cleaning up 
getc(stdin); 

回答

0

你是否打电话给sendrecv?他们不保证他们发送或接收您提供的所有数据或缓冲区。

TCP Connection Seems to Receive Incomplete Data

而且你真的应该发布一些代码,否则我们只能猜测。

+0

是发送/ recv的被称为一个循环。 但我认为,如果send()成功,那么数据应该到达目标TCP。 (并且随后通过一个或多个recv应用程序() 将在短时间内发布代码 – Rohan

2

你的假设是有缺陷的。

send()成功返回只是意味着该数据已经接受了你的内核发送 - 它仍然可以坐在你发送队列。

如果你想知道,如果该数据已经达到了另一端,你必须是应用层确认中。

(也this question见)

+0

不会是递归的 当接收方应用程序为收到的数据发送ACK时,如何确保ACK数据包的所有字节。交付 – Rohan

+0

这是事实,而在一般情况下,一个无法解决的问题,这意味着你的发送者应用程序只知道接收方已经看到*至少*它已收到的ACK的 - 它必须重发别的了。然后,您的发件人必须准备好检测并丢弃不必要地重新发送的数据。 – caf