gpt4 book ai didi

c++ - 从服务器接收传入流量

转载 作者:可可西里 更新时间:2023-11-01 02:36:44 25 4
gpt4 key购买 nike

我有以下功能设置,每 2 分钟从服务器接收一次数据。这是我第一次调用该函数,它似乎可以正常工作,但随后它在永远不会返回的 recv 调用处卡住。即使服务器没有要发送的内容,我是否需要在每次调用时分配缓冲区?

#define RCVBUFSIZE 32

void Receive()
{
UINT totalBytesRcvd = 0, bytesRcvd = 0;
char buffer[RCVBUFSIZE]; /* Buffer for string */

/* Receive up to the buffer size (minus 1 to leave space for
a null terminator) bytes from the sender */

bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0);

if (bytesRcvd)
{
buffer[bytesRcvd] = '\0';
MessageBox(0, buffer, 0, 0); //some way to display the received buffer
}
else if (bytesRcvd == SOCKET_ERROR)
{
return;
}
}

最佳答案

(1) 您的缓冲区并未真正分配,它驻留在堆栈中。您通常不必担心在堆栈上使用 32 个字节。

(2) recv 应该阻塞直到有东西要接收。您可以通过使用非阻塞套接字或使用 select 来解决这个问题。请看here供引用。

特别是,您可以

(2a) 使用 ioctlsocket将套接字设置为非阻塞模式。然后,当您调用 read 并且没有任何内容可读时,您将收到错误 EWOULDBLOCK

unsigned long non_blocking = 1;
ioctlsocket (sockClient, FIONBIO, &non_blocking);

那么阅读就变成了

bytesRcvd = recv(sockClient, buffer, RCVBUFSIZE - 1, 0);
if (bytesRcvd == -1) {
if (WSAGetLastError() == EWOULDBLOCK) {
// nothing to read now
} else {
// an actual error occurred
}
} else {
// reading was successful. Call to MsgBox here
}

(2b) 或者,您可以调用 select在实际调用read之前判断是否有数据要读取。

struct timeval timeout;
timeout.tv_usec = 0;
timeout.tv_sec = 0;

fd_set r;
FD_ZERO (&r);
FD_SET (sockClient, &r);
switch (select (sockClient + 1, &r, NULL, NULL, &timeout)) {
case -1:
// error
break;
case 0:
// nothing to read
break;
case 1:
// you may call read ()
break;
}

关于c++ - 从服务器接收传入流量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4245134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com