0

我在本地机器上运行了一个代理服务器,用于在冲浪时缓存图像。我将浏览器设置为 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_ 是非阻塞的。知道如何解决这个问题吗?

4

2 回答 2

2

您没有对recv.

这里有两个层次。

第一个是,您将 0 和 -1 混为一谈。0 表示远程对等方关闭了其发送的一半连接,因此您的代码在这里做了正确的事情,也关闭了它的套接字。-1 表示除了接收到数据之外还发生了一些事情。它可能是永久错误、临时错误,或者只是来自堆栈的通知,即除了接收到数据之外还发生了一些事情。您的代码将所有这些可能性集中在一起,除此之外,将它们视为与远程对等点关闭连接时相同。

recv第二个层次是,从套接字不再有用的意义上来说,并非所有从 -1 获取的原因都是“错误”。我想如果你开始检查 -1 然后打电话WSAGetLastError找出你为什么得到 -1,你会得到WSAEWOULDBLOCK,这是正常的,因为你有一个非阻塞套接字。这意味着recv调用不能返回数据,因为它必须阻塞程序的执行线程才能这样做,并且你告诉 Winsock 你想要非阻塞调用。

一个天真的解决方法是不跳出循环,WSAEWOULDBLOCK但这只是意味着你一次recv又一次地消耗 CPU 时间,直到它返回数据。这违背了非阻塞套接字的全部意义,即它们让您的程序在网络繁忙时做其他事情。您应该使用 , 之类的函数selectWSAAsyncSelect或者WSAEventSelect在调用 API 函数可能再次成功时收到通知。在那之前,你不叫它。

您可能想访问Winsock 程序员的常见问题解答。(免责声明:我是它的维护者。)

于 2009-11-22T15:07:25.517 回答
0

您是否在 HTTP 级别分析了事务,即检查了标头?

您是否考虑了分块传输之类的事情?

我没有明确的答案,部分原因是这里没有给出详细信息。

于 2009-11-22T11:56:39.800 回答