Domanda

I am developing a server for file transfer applications. Files are sent from an android phone to my server.

When the file size is small, it works smoothly. But when the file size is large (>2MB), the server does not receive the entire packet.

int recv(
  _In_   SOCKET s,
  _Out_  char *buf,
  _In_   int len,
  _In_   int flags
);

The value of len in the recv function was set to 20000 initially and when I changed it to 8000, it started working.

Surprisingly, this happens only in Release mode in Visual Studio.

I used wireshark to capture the logs from my mobile device. When the server is running on debug mode, the handset sends all the data, but when the server is running on release mode, handset does not send the entire data. (this is when value of len was set to 20000).

However, if I send large files through a PC based client, (client being on same machine as server), the value of len can be kept at 20000.

Has anyone faced such problems? What is the reason for such behaviour?

Note: I am developing on Windows using Visual studio.

È stato utile?

Soluzione

The len argument to recv specifies the maximum number of bytes to read. There is no guarantee that recv will block until it reads exactly this amount; it may return after reading any smaller number of bytes. The actual amount of data read is noted in the return value.

You need to call recv repeatedly yourself if you want to read a set number of bytes

int read_exact(SOCKET s, char* buf, int len)
{
    int remaining = len;
    do {
        int ret = recv(s, buf, remaining, 0);
        if (ret == 0) {
            break;
        }
        if (ret != SOCKET_ERROR ) {
            remaining -= ret;
            buf += ret;
        }
    } while (ret != SOCKET_ERROR && remaining > 0);
    return (ret==SOCKET_ERROR? SOCKET_ERROR : len - remaining);
}

Altri suggerimenti

Neither recv or send 's len parameter is an exact value, it's just a hint on how much data you can maximally store ( for recv ) or how much you want to send, each function returns either an error or the number of bytes processed which can be less than what you requested, ignoring this case will result in random like errors since either the server doesn't fully send it or the client doesn't received the correct amount.

The safest way to do this is to send a header each time which will ensure that you'll know the amount of data you are about to receive, on the client you expect that structure then the data. Since in this case you know exactly how much data you will send/recv you can rely on that and keep calling the functions until they either fail or eventually do what you want ( send all the data or recv all the data ).

Also never try to send too big chunks at once since it will will fill up the winsock internal buffers so the function will return which is reasonable since it's unable to process your request because it needs to send the data first or there is no more room left to receive more.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top