views:

77

answers:

2

hey guys, 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?

A: 

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.

jldupont
+2  A: 

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

Warren Young