知道客户端何时从C中的套接字读取

时间:2015-05-06 04:54:55

标签: c sockets

我在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);

 }

当我在一次文件传输后在服务器上进行读取时,程序会挂起。

2 个答案:

答案 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 ...)会发出数据结束信号

这仍然是一个简单的协议,没有错误恢复,但至少它可以在没有事件发生时工作。