【问题标题】:Knowing when Client has finished reading from the socket in C知道客户端何时完成从 C 中的套接字读取
【发布时间】:2015-05-06 04:54:55
【问题描述】:

我正在用 c 编写一个客户端-服务器程序,我必须将多个图像文件从服务器发送到客户端。服务器有没有办法知道客户端何时完成从套接字读取,在本地创建图像文件并成功写入?附言我已经尝试向套接字发送消息,当我尝试从服务器读取套接字时,程序挂起。任何帮助都感激不尽。 这是服务器代码中的一个函数,它将文件发送到套接字:

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

 }

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

【问题讨论】:

  • 欢迎来到 StackOverflow。服务器知道的唯一方法是客户端将消息发送回服务器。如果您的服务器在尝试读取该消息时挂起,那么您没有正确编码读取。请显示您的实际代码,或 MCVE 演示问题。
  • 服务器会在读取中挂起,因为它是一个阻塞调用,并且会一直等到它收到一些东西。
  • 是的,但我正在让客户端将消息“准备好”写入套接字;服务器无法读取。
  • 你试过在 write() 之后关闭客户端的套接字吗?

标签: c sockets


【解决方案1】:

你的问题在客户端:

while(( num = recv(sockfd,buf,256,0))>0)

recv() 只会在文件末尾返回0 - 即当服务器关闭套接字的发送端时。但是您的服务器没有这样做 - 它正在等待来自客户端的响应。这意味着你陷入僵局。

如果您想在一个连接中发送多张图片,您需要向您的客户端发送一些信息,以便它知道一张图片何时结束。一种方法是首先向您的客户端发送它应该期望的文件大小,然后是文件数据。然后客户端可以跟踪它收到了多少字节,然后发送“就绪”响应。

【讨论】:

  • 谢谢。我一定会尝试的。
【解决方案2】:

你需要一种协议来允许:

  • 服务器告诉客户端一切都写好了
  • 客户端告诉服务器所有内容都已读取

如果你只发送一个文件,最简单的方法是在发送完所有数据后使用shutdown(sockfd, SHUT_WR)服务器端。这样,客户端将从recv 信号结束返回 0,并能够发送其确认。但是你不能再在socket服务器端写了。

如果您希望能够发送多个文件,您将不得不设想一种更聪明的协议。一个常见的方法是发送前面带有大小的数据块

short sz = htons(n);  /* deals with possible endianness problems */
send(sockfd, &sz, sizeof(short), 0)
send(sockfd, buf, n);

sz == 0(没有 buf ...)将表示数据结束

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-07
    • 1970-01-01
    • 2012-11-01
    • 1970-01-01
    • 2016-03-02
    • 2012-07-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多