WSASend在将数据实际发送到设备之前返回

WSASend returns before sending data to device actually

本文关键字:返回 数据 WSASend      更新时间:2023-10-16

很抱歉对我的问题描述不当。

我的程序所做的是连接服务器,发送一些数据并关闭连接。我简化了我的代码,如下所示:

WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
connect(s, (const sockaddr*)&dstAddr, sizeof(dstAddr));
send(s, (const char*)pBuffer, fileLen, 0);
shutdown(s, SD_SEND);
closesocket(s);
WSACleanup();

在找到导致通信关闭的 RST 之前,服务器仅接收到部分数据。

我编写了一个模拟服务器程序来接受连接和接收数据,但模拟器可以获取所有数据。因为我无法访问服务器的源代码,所以我不知道其中是否有问题。有没有办法通过在客户端中添加一些代码来避免此错误,或者我可以证明服务器程序中有问题吗?


设置套接字的延迟选项可以修复该错误。但是我需要给出一个神奇的数字来表示逗留时间的价值。

linger l;
l.l_onoff = 1;
l.l_linger = 30;
setsockopt(socket, SOL_SOCKET, SO_LINGER, (const char*)&l, sizeof(l));

WSASend 在将数据实际发送到设备之前返回

正确。

我创建了一个非阻塞套接字并尝试将数据发送到服务器。

WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, WSA_FLAG_OVERLAPPED)

不,你没有。您创建了一个重叠的 I/O 套接字。

执行后,返回值SOCKET_ERROR,WSAGetLastError() 返回WSA_IO_PENDING。然后我调用了WSAWaitForMultipleEvents来等待事件被设置。在它返回WSA_WAIT_EVENT_0后,我调用WSAGetOverlappedResult来获取实际发送的数据长度,它与我发送的值相同。

因此,所有数据都被传输到套接字发送缓冲区中。

我首先调用WSASocket,然后调用WSASend/WSAWaitForMultipleEvents/WSAGetOverlappedResult几次以发送一堆数据,并在最后关闭套接字。

因此,在该过程结束时,所有数据和收盘都已传输到套接字发送缓冲区。

但是服务器无法接收所有数据,我使用Wireshark查看tcp数据包,发现客户端在所有数据包发送之前发送了RST。

这可能是由于多种原因,如果不看到一些代码,就无法确定这些原因。

如果我在调用closesocket之前睡了1分钟,那么服务器将接收所有数据。

同样,这将取决于代码中发生的其他情况。

似乎WSASend/WSAWaitForMultipleEvents/WSAGetOverlappedResult在将数据发送到服务器之前返回

正确。

数据保存在缓冲区中,等待发送出去。

正确。

当我呼叫closesocket时,通信已关闭。

正确。

他们没有按照我的期望工作。

所以你的期望是错误的。

我做错了什么?此问题仅发生在特定的PC中,应用程序在其他PC中运行良好。

如果不看到一些代码,就不可能回答。发出 RST 的通常原因是对等方已将数据写入您已经关闭的连接:换句话说,应用程序协议错误;但还有其他可能性。