[英]Winsock2, BitCoin Select() returns data to read, Recv() returns 0 bytes
I made a connection to BitCoin node via WinSock2.我通过 WinSock2 连接到比特币节点。 I sent the proper "getaddr" message and then the server responds, the replied data are ready to read, because Select() notifies this, but when I call Recv() there are 0 bytes read.
我发送了正确的“getaddr”消息,然后服务器响应,回复的数据已准备好读取,因为 Select() 通知了这一点,但是当我调用 Recv() 时,读取了 0 个字节。
My code is working OK on localhost test server.我的代码在本地主机测试服务器上运行正常。 The incomplete "getaddr" message (less than 24 bytes) is NOT replied by BitCoin node, only proper message, but I can't read the reply with Recv().
BitCoin 节点不回复不完整的“getaddr”消息(小于 24 字节),只有正确的消息,但我无法使用 Recv() 读取回复。 After returning 0 bytes, the Select() still returns there are data to read.
返回 0 字节后,Select() 仍然返回有数据可读。
My code is divided into DLL which uses Winsock2 and the main() function.我的代码分为使用 Winsock2 的 DLL 和 main() function。
Here are key fragments:以下是关键片段:
struct CMessageHeader
{
uint32_t magic;
char command[12];
uint32_t payload;
uint32_t checksum;
};
CSocket *sock = new CSocket();
int actual; /* Actually read/written bytes */
sock->connect("109.173.41.43", 8333);
CMessageHeader msg = { 0xf9beb4d9, "getaddr\0\0\0\0", 0, 0x5df6e0e2 }, rcv = { 0 };
actual = sock->send((const char *)&msg, sizeof(msg));
actual = sock->select(2, 0); /* Select read with 2 seconds waiting time */
actual = sock->receive((char *)&rcv, sizeof(rcv));
The key fragment of DLL code: DLL代码的关键片段:
int CSocket::receive(char *buf, int len)
{
int actual;
if ((actual = ::recv(sock, buf, len, 0)) == SOCKET_ERROR) {
std::ostringstream s;
s << "Nie mozna odebrac " << len << " bajtow.";
throw(CError(s));
}
return(actual);
}
If select()
reports the socket is readable, and then recv()
returns 0 afterwards, that means the peer gracefully closed the connection on their end (ie, sent a FIN
packet to you), so you need to close your socket.如果
select()
报告套接字可读,然后recv()
之后返回 0,这意味着对等端优雅地关闭了他们端的连接(即,向您发送了一个FIN
数据包),因此您需要关闭您的套接字。
On a side note, recv()
can return fewer bytes than requested, so your receive()
function should call recv()
in a loop until all of the expected bytes have actually been received, or an error occurs (same with send()
, too).附带说明一下,
recv()
可以返回比请求更少的字节,因此您的receive()
function 应该在循环中调用recv()
直到实际收到所有预期的字节,或者发生错误(与send()
, 也)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.