开发者

C Socket File Transfer Error

开发者 https://www.devze.com 2023-03-25 16:57 出处:网络
I have a file transfer code written in C using windows sockets which seems to work but keeps transferring fewer than the desired number of bytes of the file.

I have a file transfer code written in C using windows sockets which seems to work but keeps transferring fewer than the desired number of bytes of the file.

Any ideas?

Send code:

while(!feof(fp))
{
   bzero(bufferin,256);
   fread(bufferin,sizeof(char开发者_开发知识库),255,fp);
   send(remsock,bufferin,255,0);

   if(n < 0)
      error("ERROR writing to socket");
}
send(remsock,"done",255,0);

Accept code:

while(1)
{
    recv(sockfd,buffer,255,0);
    if(compare(buffer,"done") == 0)
        break;  
    fwrite(buffer,1,255,fplog);
}
printf("File Transfer complete\n\n");


The problem is that send and recv work differently than what you may expect.

send(remsock,bufferin,255,0); /* Write MAX 255. May write less than 255. */
recv(sockfd,buffer,255,0); /* Read MAX 255. May read less than 255. */

Usually the problem lies on the receive side. So you should read in a loop.

while (bytes_to_go) {
    bytes = recv(...);
    /* Check bytes. */
    bytes_to_go -= bytes;
}


As others have stated, you MUST look at the return values of all the functions you are calling, eg:

Sending:

while (!feof(fp))
{
    int nRead = fread(bufferin, sizeof(char), 256, fp);
    if (nRead <= 0)
        error("ERROR reading file");

    char *pBuf = bufferin;
    while (nRead > 0)
    {
        int nSent = send(remsock, pBuf, nRead, 0);
        if (nSent == SOCKET_ERROR)
        {
            if (WSAGetLastError() != WSAEWOULDBLOCK)
                error("ERROR writing to socket");

            fd_set writefd;
            FD_ZERO(&writefd);
            FD_SET(remsock, &writefd);

            if (select(0, NULL, &writefd, NULL, NULL) != 1)
                error("ERROR waiting to write to socket");

            continue;
        }

        if (nSent == 0)
            error("DISCONNECTED writing to socket");

        pBuf += nSent;
        nRead -= nSent;
    }
}

closesocket(remsock);

Receiving:

while(1)
{
    int nRecv = recv(sockfd, buffer, 256, 0);
    if (nRecv == SOCKET_ERROR)
    {
        if (WSAGetLastError() != WSAEWOULDBLOCK)
            error("ERROR reading from socket");

        fd_set readfd;
        FD_ZERO(&readfd);
        FD_SET(sockfd, &readfd);

        if (select(0, &readfd, NULL, NULL, NULL) != 1)
            error("ERROR waiting for data from socket");

        continue;
    }

    if (nRecv == 0)
        break;

    char *pBuf = buffer;
    while (nRecv > 0)
    {
        int nWritten = fwrite(pBuf, sizeof(char), nRecv, fplog);
        if (nWritten <= 0)
            error("ERROR writing to file");

        pBuf += nWritten;
        nRecv -= nWritten;
    }
}

printf("File Transfer complete\n\n"); 


Take a look at sendfile() and recv()'s MSG_WAITALL.


It appears that this combination works and gives a correct checksum for the files. It is important to use fclose() at the end as well as send the correct number of bytes by capturing the return values as people said. Thanks for the responses though I did get a bit concerned when people mentioned that send and rcv functions send a max of 255 in my case of bytes and may send less. I've run many trials and have not noticed a transfer issue.

Send code:

FILE *fp;
fp = fopen("c:\\file.txt", "rb");

while(!feof(fp))
{
   bzero(buffer,256);
   n = fread(buffer,sizeof(char),255,fp);
   send(remsock,buffer,n,0);

   if(n < 0)
      error("ERROR writing to socket");
}
send(remsock,"done",255,0);
fclose(fp);

Receive code:

FILE *fp;
fp = fopen("c:\\receivedfile.txt", "wb");

while(1)
{
    n = recv(sockfd,buffer,255,0);
    if(compare(buffer,"done") == 0)
        break;  
    fwrite(buffer,1,n,fp);
}
printf("File Transfer complete\n\n");
fclose(fp);
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号