我正在用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循环的终止条件),这会导致服务器端的不定式循环。 附:所有其他功能都没有问题(例如发送和接收文件大小,文件大小的实际数量等等),我已经对它们进行了全部测试。而且客户端也没有问题。
以下是问题的截图
所以任何人都可以帮助我解决这个问题,我一直试图解决这个问题几周,非常感谢!
答案 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");