我制作了一个客户端服务器应用程序,其中客户端发送文件(即ODT,PDF,MP3,MP4等),服务器接收文件。
我将文件分成块,然后在while循环中传输它们。 下面我给出了客户端和服务器的主要逻辑。
当我使用127.0.0.1进行环回时,此代码可以成功运行。
但是当我在两台不同的PC上运行客户端和服务器时,在发送文件后客户端退出但服务器继续接收,然后我必须按 ctrl ^ C 。即使客户端的文件大小仅为4.2 MB左右,服务器端的文件大小也超过1GB。
并且在环回中我没有遇到这样的问题。
请告诉我所需的更正。
client.c
#define SIZE 512 // or anything else
char sendbuff[SIZE];
FILE *fr;
fr = fopen("1.mp3","r");
while(!feof(fr)){
count = fread(sendbuff, SIZE,1,fr);
count = send(clientsd, sendbuff,SIZE,0); //clientsd is socket descriptor.
}
send(clientsd, "xyz", 3, 0); //sending '1'. tells server, transmission is over now.
close(fr);
server.c
#define SIZE 512 // same as client side
char recvbuff[SIZE];
FILE *fw;
fw = fopen("2.mp3","w");
while(1){
count = recv(connsd, recvbuff, SIZE,0);
if(!strcmp(recvbuff,"xyz"))
break;
fwrite(recvbuff,SIZE, 1, fw);
memset(recvbuff,0,SIZE);
}
printf("Exit while\n");
fclose(fw);
任何其他简单有效的方法吗?
注意:我已经改变了我的问题。这里有一些答案在我的旧问题上,我已经传达了#34; 1"而不是" xyz"。这是一个错误。
答案 0 :(得分:1)
最明显的问题是服务器端的停止条件。
假设接收的第一个字节是'1'
(0x31)而不是传输结束,但它可能是数据的一个字节(如果文件中块的第一个字节实际上是{{ 1}})。因此,您需要一些其他方式来表示文件的结尾。一种可能性是对每个发送的数据包使用包装,例如,在每个数据包发送特定值(例如' 1')之后跟随长度,并且当传输完成时发送' 0'表示转移已完成。
我能看到的其他问题是:
您将文件作为读取文本(" r")打开并写入文本(" w"),如果EOF序列出现在中间,将停止处理文件,而不是你需要打开它们读/写二进制(" rb" /" wb"分别)。
你使用512字节的块,如果文件不是512字节的倍数怎么办?