结束“recv()”使用 Winsock 读取所有信息时循环

发布于 2024-09-11 16:41:35 字数 865 浏览 11 评论 0原文

我的winsock 的recv() 循环遇到问题。我试图在 iResult==0 时终止循环,但是,循环仅在套接字关闭时结束。它似乎挂在最后一个recv()处,其中iResult等于0。那么关于如何有效地终止循环有什么想法吗?我的最终目标(无论 iResult == 0 与否;也许我的处理方式是错误的)是在读取所有发送的信息后停止循环。这是循环。

    do
    {
        iResult = recv(socket, recvbuf, BUFLEN-1, 0);
        if(iResult > 0){
            // Null byte :)
            // Remove that garbage >:(
            recvbuf[iResult] = '\0';
            printf("Recvbuf: %s\n\n\niResult: %d\n",recvbuf,iResult);
            continue; // working properly
        }
        else if(iResult == 0)
            // Connection closed properly
            break;
        else
        {
            printf("ERROR! %ld",WSAGetLastError());
            break;
        }
    } while(iResult > 0);

就像我说的,我正在接收所有数据,我只是无法退出循环。下一步是将数据写回服务器,但它会挂在这里直到 ping 超时。套接字是 SOCK_STREAM,BUFLEN 定义为 0x200

谢谢

I am having an issue in my recv() loop for winsock. I am trying to terminate the loop when iResult==0, however, the loop only ends when the socket closes. It appears to be hanging at the very last recv() where iResult would equal 0. So any ideas on how to terminate the loop effectively? My ultimate goal (whether iResult == 0 or not; perhaps I am going about this the wrong way) is to stop the loop when all the sent information has been read. Here is the loop.

    do
    {
        iResult = recv(socket, recvbuf, BUFLEN-1, 0);
        if(iResult > 0){
            // Null byte :)
            // Remove that garbage >:(
            recvbuf[iResult] = '\0';
            printf("Recvbuf: %s\n\n\niResult: %d\n",recvbuf,iResult);
            continue; // working properly
        }
        else if(iResult == 0)
            // Connection closed properly
            break;
        else
        {
            printf("ERROR! %ld",WSAGetLastError());
            break;
        }
    } while(iResult > 0);

Like I said, I am receiving all the data, I just cannot exit the loop. The next step would to be write data back to the server, but it hangs here until ping timeout. Socket is SOCK_STREAM and BUFLEN is defined as 0x200

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

太傻旳人生 2024-09-18 16:41:35

默认情况下,recv 如果没有数据要接收则阻塞

如果没有可用的传入数据
套接字、recv 调用块和
等待数据到达
为 WSARecv 定义的阻塞规则
未设置 MSG_PARTIAL 标志
除非套接字是非阻塞的。在
在这种情况下,SOCKET_ERROR 的值为
返回错误代码设置为
WSAEWOULBlock。所选择的,
WSAAsyncSelect 或 WSAEventSelect
函数可用于确定
当更多数据到达时。

您可以使用 ioctlsocket 放置套接字在非阻塞模式下:

u_long iMode = 1;
ioctlsocket(socket, FIONBIO, &iMode);

编辑:这是我在早期版本中提出的setsockopt建议,然后删除(请参阅评论):

您可以使用setsockopt
带有 SO_RCVTIMEO 选项的函数
将套接字设置为在 recv 上超时
如果没有可用数据。


By default, instead of returning 0, recv blocks if there's no data to receive :

If no incoming data is available at
the socket, the recv call blocks and
waits for data to arrive according to
the blocking rules defined for WSARecv
with the MSG_PARTIAL flag not set
unless the socket is nonblocking. In
this case, a value of SOCKET_ERROR is
returned with the error code set to
WSAEWOULDBLOCK. The select,
WSAAsyncSelect, or WSAEventSelect
functions can be used to determine
when more data arrives.

You can use ioctlsocket to put the socket in non-blocking mode:

u_long iMode = 1;
ioctlsocket(socket, FIONBIO, &iMode);

EDIT: Here's the setsockopt suggestion that I made in an earlier rev, then removed (see comments):

You can use the setsockopt
function with the SO_RCVTIMEO option
to set the socket to timeout on recv
if no data is available.

勿挽旧人 2024-09-18 16:41:35

当您设计 TCP 通信机制时,您必须定义消息边界。
(通常是\r\n)。就其本身而言,tcp 不知道边界;你必须自己做这件事。
recv() 调用可能并不总是在消息边界上返回。一个 send() 可能会在另一端拆分为多个 receive()-s。

When you design a TCP communication mechanism you have to define message boundaries.
(often \r\n). In of itself, tcp doesn't know about boundaries; you have to do this yourself.
The recv() call may not always return on a message boundary. One send() might get split into multiple recv()-s on the other end.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文