我在c中编写客户端 - 服务器程序,我必须从服务器向客户端发送多个图像文件。有没有办法让服务器知道客户端何时从套接字读取,在本地创建映像文件,并成功写入它?附:我已经尝试向套接字发送消息,当我尝试从服务器读取套接字时,程序挂起。任何帮助都感激不尽。 这是服务器代码中的一个函数,它将文件发送到socket:
while(1)
{
unsigned char buf[256] = {0};
int n = fread(buf,1,256,fp);
if(n>0) { send(sockfd,buf,n,0); }
if(n<256) {
if(feof(fp))
printf("Sent to socket\n");
break;
}
}
fclose(fp);
}
char buf[5]
read(sockfd,buf,5);
if(strcmp(buf,"ready")==0) //send more files
这是客户端写入文件的函数:
FILE* fp;
fp = fopen(file_path,"ab");
char buf[256];
int num;
int total=0;
while(( num = recv(sockfd,buf,256,0))>0)
{
total+=num;
fwrite(buf,1,num,fp);
}
fclose(fp);
write(sockfd,"ready",5);
}
当我在一次文件传输后在服务器上进行读取时,程序会挂起。
答案 0 :(得分:4)
问题在于客户端:
while(( num = recv(sockfd,buf,256,0))>0)
recv()
只会在文件结束时返回0
- 即当服务器关闭套接字的发送方时。但是,您的服务器并没有这样做 - 它正在等待客户端的响应。这意味着你陷入僵局。
如果要在一个连接中发送多个图像,则需要向客户端发送一些信息,以便在一个图像结束时告知它。一种方法是首先向客户端发送它应该期望的文件大小,然后是文件数据。然后,客户端可以跟踪它收到的字节数,并发送&#34; ready&#34;之后再回答。
答案 1 :(得分:2)
您需要一种协议才能允许:
如果您只发送一个文件,最简单的方法是在发送所有数据后使用 [self dismissViewControllerAnimated:YES completion:nil];
服务器端。这样,客户端将从shutdown(sockfd, SHUT_WR)
信令结束数据返回0并且能够发送其确认。但是你不能再在套接字服务器端写。
如果您希望能够发送多个文件,则必须想象一个更聪明的协议。一个常见的方法是发送以其大小
开头的数据集团recv
short sz = htons(n); /* deals with possible endianness problems */
send(sockfd, &sz, sizeof(short), 0)
send(sockfd, buf, n);
(没有buf ...)会发出数据结束信号
这仍然是一个简单的协议,没有错误恢复,但至少它可以在没有事件发生时工作。