通过winsocket接收图像

发布于 2024-08-12 12:33:48 字数 601 浏览 10 评论 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_ 是非阻塞的。知道如何解决这个问题吗?

i have a proxy server running on my local machine used to cache images while surfing. I set up my browser with a proxy to 127.0.0.1, receive the HTTP requests, take the data and send it back to the browser. It works fine for everything except large images. When I receive the image info, it only displays half the image (ex.: the top half of the google logo) heres my code:

  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);

the socketClient_ is non-blocking. Any idea how to fix this problem?

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

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

发布评论

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

评论(2

小傻瓜 2024-08-19 12:33:48

您没有对 recv 的可能返回值进行足够精细的区分。

这里有两个层次。

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

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

一个天真的解决方法是不跳出 WSAEWOULDBLOCK 上的循环,但这仅仅意味着您会一次又一次地调用 recv 直到它返回数据为止,从而消耗 CPU 时间。这违背了非阻塞套接字的全部要点,即它们让您的程序在网络繁忙时执行其他操作。您应该使用 selectWSAAsyncSelectWSAEventSelect 等函数,以便在对 API 函数的调用可能再次成功时收到通知。在那之前,你不会调用它。

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

You're not making fine enough distinctions among the possible return values of recv.

There are two levels here.

The first is, you're lumping 0 and -1 together. 0 means the remote peer closed its sending half of the connection, so your code does the right thing here, closing its socket down, too. -1 means something happened besides data being received. It could be a permanent error, a temporary error, or just a notification from the stack that something happened besides data being received. Your code lumps all such possibilities together, and on top of that treats them the same as when the remote peer closes the connection.

The second level is that not all reasons for getting -1 from recv are "errors" in the sense that the socket is no longer useful. I think if you start checking for -1 and then calling WSAGetLastError to find out why you got -1, you'll get WSAEWOULDBLOCK, which is normal since you have a non-blocking socket. It means the recv call cannot return data because it would have to block your program's execution thread to do so, and you told Winsock you wanted non-blocking calls.

A naive fix is to not break out of the loop on WSAEWOULDBLOCK but that just means you burn CPU time calling recv again and again until it returns data. That goes against the whole point of non-blocking sockets, which is that they let your program do other things while the network is busy. You're supposed to use functions like select, WSAAsyncSelect or WSAEventSelect to be notified when a call to the API function is likely to succeed again. Until then, you don't call it.

You might want to visit The Winsock Programmer's FAQ. (Disclaimer: I'm its maintainer.)

表情可笑 2024-08-19 12:33:48

您是否分析过 HTTP 级别的事务(即检查标头)?

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

我没有明确的答案,部分原因是这里缺乏细节。

Have you analyzed the transaction at the HTTP level i.e. checked Headers?

Are you accounting for things like Chunked transfers?

I do not have a definite answer in part because of the lack of details given here.

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