2009-11-21 41 views
0

我有一台运行在本地机器上的代理服务器,用于在浏览时缓存图像。我使用代理将浏览器设置为127.0.0.1,接收HTTP请求,获取数据并将其发送回浏览器。它适用于除大型图像以外的所有应用。当我接收图像信息,只显示一半的图像(例如:谷歌标志的上半部分)继承人我的代码:通过winsocket接收图像

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_是非阻塞的。任何想法如何解决这个问题?

回答

2

您在recv的可能返回值中没有做出足够的区分。

这里有两个级别。

首先是,你将0和-1混合在一起。 0表示远程节点关闭了它的一半连接,所以你的代码在这里做了正确的事情,也关闭了它的套接字。 -1表示除了接收数据之外发生了一些事情它可能是一个永久性错误,一个暂时的错误,或者只是一个从堆栈发出的通知,除了收到数据之外发生了一些事情。你的代码将所有这些可能性结合在一起,并且在远程对等关闭连接时将它们视为相同。

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

一个天真的修复方法是不打破WSAEWOULDBLOCK的循环,但这只是意味着你一次又一次地调用recv,直到它返回数据为止。这违背了非阻塞套接字的全部要点,即它们让您的程序在网络繁忙时做其他事情。你应该使用像select,WSAAsyncSelectWSAEventSelect这样的函数在API函数的调用很可能再次成功时被通知。在此之前,你不会这样称呼它。您可能想访问The Winsock Programmer's FAQ。 (免责声明:我是其维护者。)

0

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

你是否会考虑诸如Chunked传输的内容?

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