WSASend在将数据实际发送到设备之前返回
WSASend returns before sending data to device actually
很抱歉对我的问题描述不当。
我的程序所做的是连接服务器,发送一些数据并关闭连接。我简化了我的代码,如下所示:
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 的通常原因是对等方已将数据写入您已经关闭的连接:换句话说,应用程序协议错误;但还有其他可能性。
- 为什么我们使用在C++中返回数据结构的函数?
- 如何通过另一个对象中的命令正确地从一个对象返回数据
- FFmpeg av_read_frame从音频流返回数据包
- 扩展 QStandardItem 不会返回数据
- C++ 根据给定的类型名从变量返回数据
- YAML-CPP的顺序返回数据
- 从全局 CUDA 函数返回数据
- C++ ostream 从对象数组返回数据
- 现代C++.从继续执行的工作线程返回数据结构
- 使用 JNI 通过从C++到 Java 的指针返回数据
- 为什么返回数据结构而不是指针弄乱了我的数据的完整性
- C++Curl,如何读取返回数据
- WSARecv()能否立即返回数据
- 处理 char * 的正确方法在 swig/python 中返回数据
- 如何使用 cppunit 断言宏来检查返回数据类型的预处理器值
- C++函数,不返回返回数据
- 通过.NET中的指针从本机方法返回数据
- 从if语句返回数据
- 更快地以数组形式返回数据的c++接口
- 模板,在派生类中返回数据的通用方法