通过winsocket接收图像
我的本地计算机上运行着一个代理服务器,用于在冲浪时缓存图像。我使用 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您没有对
recv
的可能返回值进行足够精细的区分。这里有两个层次。
第一个是,你将 0 和 -1 混为一谈。 0 表示远程对等方关闭了其发送的一半连接,因此您的代码在这里做了正确的事情,也关闭了其套接字。 -1 表示除了接收数据之外还发生了一些事情。它可能是永久错误、临时错误,或者只是来自堆栈的通知,表明除了接收数据之外还发生了某些情况。您的代码将所有这些可能性集中在一起,最重要的是,将它们视为与远程对等方关闭连接时相同的方式。
第二个层次是,并非所有从
recv
获取 -1 的原因都是“错误”,因为套接字不再有用。我认为如果您开始检查 -1,然后调用WSAGetLastError
来找出为什么您得到 -1,您将得到WSAEWOULDBLOCK
,这是正常的,因为您有一个非-阻塞套接字。这意味着recv
调用无法返回数据,因为它必须阻塞程序的执行线程才能返回数据,并且您告诉 Winsock 您想要非阻塞调用。一个天真的解决方法是不跳出 WSAEWOULDBLOCK 上的循环,但这仅仅意味着您会一次又一次地调用
recv
直到它返回数据为止,从而消耗 CPU 时间。这违背了非阻塞套接字的全部要点,即它们让您的程序在网络繁忙时执行其他操作。您应该使用select
、WSAAsyncSelect
或WSAEventSelect
等函数,以便在对 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 callingWSAGetLastError
to find out why you got -1, you'll getWSAEWOULDBLOCK
, which is normal since you have a non-blocking socket. It means therecv
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 callingrecv
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 likeselect
,WSAAsyncSelect
orWSAEventSelect
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.)
您是否分析过 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.