while循环判断条件为阻塞函数的情况

wangying_great 2017-08-20 03:24:24
第一次发帖,可能有好多东西不会,请谅解;

服务器通过sock_data句柄将文件内容发送给客户端,在发送完毕后,通过sock_control句柄,发送一个226的数字给客户端,表示文件已经发完。

客户端while循环,通过sock_data句柄,接收数据并打印出来,之后通过sock_con得到服务器传输完成的消息。

现在的问题是:当客户端接收完所有数据时,我认为它会阻塞在while ((num_recvd = recv(sock_data, buf, MAXSIZE, 0)) > 0) 这里,因为数据已经取完了,recv的返回值好像只有-1(出错),0(对端关闭),正数(接收到的字节数),所以没有数据时,它不就阻塞在这里了吗?所以客户端程序怎么能跳出这个while循环,去接收服务器完成的发送的消息呢?

(也不知道自己是否表述清楚了。。。)

服务器一侧的程序:
int ftserve_list(int sock_data, int sock_control)
{
………………………………
/* 通过数据连接,发送tmp.txt 文件的内容 */
while ((num_read = fread(data, 1, MAXSIZE, fd)) > 0)
{
if (send(sock_data, data, num_read, 0) < 0)
perror("err");

memset(data, 0, MAXSIZE);
}

fclose(fd);

send_response(sock_control, 226); // 发送应答码 226(关闭数据连接,请求的文件操作成功)

return 0;
}

客户端一侧的程序:
/* 接收服务器传来的数据 */
while ((num_recvd = recv(sock_data, buf, MAXSIZE, 0)) > 0)
{
printf("%s", buf);
memset(buf, 0, sizeof(buf));
}

if (num_recvd < 0)
perror("error");

/* 等待服务器完成的消息 */
if (recv(sock_con, &tmp, sizeof tmp, 0) < 0)
{
perror("client: error reading message from server\n");
return -1;
}
...全文
636 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
wangying_great 2017-08-21
  • 打赏
  • 举报
回复 1
最后,再结帖之前,把这个问题解决了吧(同事看了代码之后告诉我的)。 1:服务器通过send函数将数据向socket接口发送,在发送结束后将socket接口关闭(close)。 2:客户端用while循环去接收服务器发送过来的的数据,在接收完所有数据后,本来是会阻塞在while循环那里的(因为while循环的判断条件是recv的阻塞模式),但是由于服务器在将文件发送完毕后,主动断开连接。所以导致客户端在接收完所有数据后,recv在收到服务器断开信息后,会返回一个0,这样就跳出这个循环。 3:希望将来有人遇到相同问题能够快速解决。
大米粥哥哥 2017-08-20
  • 打赏
  • 举报
回复
服务器的:send_response(sock_control, 226); // 发送应答码 226(关闭数据连接,请求的文件操作成功) 客户端的:while ((num_recvd = recv(sock_data, buf, MAXSIZE, 0)) > 0) 不知道具体的 它注释说的是 关闭数据连接 那么客户端的返回值应该是0 所以跳出循环
wangying_great 2017-08-20
  • 打赏
  • 举报
回复
对,这两个判断是在同一个函数中完成的
大米粥哥哥 2017-08-20
  • 打赏
  • 举报
回复
再弄个线程就可以了吧 那俩判断是放一个函数里面的么?
wangying_great 2017-08-20
  • 打赏
  • 举报
回复
回复一楼一下(第一次用,不知道怎么回复。。。),服务器和客户端都有两个socket接口,而且两个socket接口是不同的,一个用于传输控制消息,一个用于传送数据的。主要是为了避免客户端无法识别到底是控制消息还是数据消息。
wangying_great 2017-08-20
  • 打赏
  • 举报
回复
对滴对滴,这就是别人写的ftp程序,我看的有点不明白,不过运行的时候,好像也没出什么错,所以就准备好好分析一下这个程序,看到这里就看不懂了。
sdghchj 2017-08-20
  • 打赏
  • 举报
回复
有种东东叫非阻塞IO,参考: 无阻塞的设置方法 方法一:fcntl //文件控制函数 int flag; if (flag = fcntl(fd, F_GETFL, 0) <0) perror("get flag"); flag |= O_NONBLOCK; if (fcntl(fd, F_SETFL, flag) < 0) perror("set flag"); 方法二:ioctl //设备控制接口函数 int b_on = 1; ioctl (fd, FIONBIO, &b_on); 即便如此,这种设计不合理吧,虽然有点像FTP协议的方式。 不同socket先后发送出数据,能保证接收端也是这样按顺序接收到数据么? 更合理的方式应该只用一个socket,在发送数据前的报文头上加上数据的字节数。

69,371

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧