TCP服务器没有从客户端收到正确的字节数

时间:2015-12-08 16:55:35

标签: c

我正在用C语言做一个TCP连接的小项目,标题中提到了我的代码的问题。以下是我的代码的上传部分

客户端:

        FILE * fp = fopen(f2d, "rb+");
                    if(fp == NULL) perror("Fail to upload(client)");
                    else
                    {
                            fseek(fp, 0, SEEK_END);
                            int filesize = ftell(fp);
                            memset(buf, '\0', MAX_SIZE);
                            sprintf(buf, "%d", filesize);
                            send(serverSocket, buf, strlen(buf), 0); //send the filesize to the server
                            rewind(fp);
                            int byteNum = 0, z = 0;
                            printf("Uploading......\n");
                            while((z += byteNum) < filesize)
                            {
                                    memset(buf, '\0', MAX_SIZE);
                                    byteNum = fread(&buf, sizeof(char), sizeof(buf), fp);
                                    printf("Bytes read to buf : %d\n", byteNum);
                                    send(serverSocket, buf, sizeof(buf), 0);          
                                    printf("Totally sent bytes: %d\n", z);
                            }
                            printf("Upload completed.\n");
                    }
                    fclose(fp);

服务器端:

        printf("Upload Requested.\n");
                    f2df = fopen(buf + 4, "wb+");
                    if(f2df == NULL) perror("Fail to upload(server)");
                    else
                    {
                            memset(buf, 0, MAX_SIZE);
                            recv(clientSocket, buf, sizeof(buf), 0); //receive the filesize
                            int filesize = atoi(buf);

                            int recvNum = 0, recv_Num = 0;
                            while((recvNum += recv_Num) < filesize)
                            {
                                    memset(buf, 0, MAX_SIZE);
                                    recv_Num = recv(clientSocket, buf, sizeof(buf), 0);
                                    fwrite(&buf, sizeof(char), sizeof(buf), f2df);
                                    printf("Bytes received from recv: %d\n", recv_Num);
                                    printf("Totally received bytes: %d\n", recvNum);
                            }
                            printf("Upload completed.\n");
                    }
                    fclose(f2df);

我的代码的想法是发送和接收字节,直到它到达文件大小。但是频率非常高(好吧,有时它正常运行,所有字节都传输到服务器)服务器似乎错过了从客户端发送的一些字节(并且“recv”函数的返回值将在之后为零)客户端已将所有字节发送到服务器,这使得永远不会达到while循环的终止条件),这会导致服务器端的不定式循环。 附:所有其他功能都没有问题(例如发送和接收文件大小,文件大小的实际数量等等),我已经对它们进行了全部测试。而且客户端也没有问题。

以下是问题的截图

enter image description here

所以任何人都可以帮助我解决这个问题,我一直试图解决这个问题几周,非常感谢!

2 个答案:

答案 0 :(得分:0)

浏览整个客户端和服务器代码并修复:

1)所有那些你没有正确处理系统调用返回的结果的时间。这特别适用于recv()返回的结果,可以是负数,(错误),零,(对等关闭连接),或者一些小于或等于请求的字节数的正数 - 只有你自己的方式可以确定,许多字体已经读到了缓冲区。忘记调用中请求的字节数和之前的任何memset / bzero,和/或strlen /之后,它返回,它们都是不充分/误导。

2)所有那些你假设的时间,只是因为你请求X字节的recv()和recv()返回一个正数,那个数字就是X.

3)所有那些你调用任何str * C风格库的时候都会调用任何不能100%保证以NULL结尾的缓冲区。

答案 1 :(得分:0)

主要问题是{not}处理send()返回值,因为即使没有任何错误条件,send()也可能返回一个小于请求的值(例如,如果缓冲区是充分)。在客户端中的每个循环周期之后,将z增加读取到buf的字节数,但忽略可能已发送的字节数较少。这导致客户端循环完成而没有发送所有数据的结果,尽管错误地这样说。改变那个e。 G。到:

                            printf("Uploading......\n");
                            while (z < filesize)
                            {
                                    byteNum = fread(buf, sizeof(char), sizeof buf, fp);
                                    printf("Bytes read to buf : %d\n", byteNum);
                                    int sent = 0;
                                    while (byteNum > 0)
                                    {
                                        int ret = send(serverSocket, buf+sent, byteNum, 0);
                                        if (ret < 0) { perror("send"); goto fail; }
                                        sent += ret, byteNum -= ret;
                                        printf("Totally sent bytes: %d\n", z += ret);
                                    }
                            }
                            printf("Upload completed.\n");