我在我的本地计算机上运行了一个代理服务器,用于在冲浪时缓存图像。我使用127.0.0.1的代理设置浏览器,接收HTTP请求,获取数据并将其发送回浏览器。它适用于除大图像之外的所有内容。当我收到图像信息时,它只显示图像的一半(例如:谷歌徽标的上半部分)继承我的代码:
char buffer[1024] = "";
string ret("");
while(true)
{
valeurRetour = recv(socketClient_, buffer, sizeof(buffer), 0);
if(valeurRetour <= 0) break;
string t;
t.assign(buffer,valeurRetour);
ret += t;
longueur += valeurRetour;
}
closesocket(socketClient_);
valeurRetour = send(socketServeur_, ret.c_str(),longueur, 0);
socketClient_是非阻塞的。知道如何解决这个问题吗?
答案 0 :(得分:2)
你在recv
的可能返回值之间没有做出足够的区别。
这里有两个级别。
首先,你将0和-1混为一谈。 0表示远程对等体关闭了其发送的一半连接,因此您的代码在这里做正确的事情,也关闭它的套接字。 -1表示除了收到数据之外发生的事情。它可能是一个永久性错误,一个临时错误,或者只是来自堆栈的通知,除了接收数据之外还发生了一些事情。您的代码将所有这些可能性整合在一起,并且最重要的是将它们视为远程对等方关闭连接时的相同。
第二个层次是,从recv
获取-1的所有原因并不是“套接字不再有用”的“错误”。我想如果你开始检查-1然后调用WSAGetLastError
来找出你得到-1的原因,你将得到WSAEWOULDBLOCK
,这是正常的,因为你有一个非阻塞套接字。这意味着recv
调用无法返回数据,因为它必须阻止程序的执行线程这样做,并且你告诉Winsock你想要非阻塞调用。
一个天真的解决方法是不要突破WSAEWOULDBLOCK
上的循环,但这只是意味着你一次又一次地调用recv
的CPU时间,直到它返回数据为止。这违背了非阻塞套接字的全部要点,即它们让您的程序在网络繁忙时执行其他操作。当API函数的调用可能再次成功时,您应该使用select
,WSAAsyncSelect
或WSAEventSelect
等函数进行通知。在那之前,你不要打电话。
您可能想访问The Winsock Programmer's FAQ。 (免责声明:我是它的维护者。)
答案 1 :(得分:0)