免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1629 | 回复: 4
打印 上一主题 下一主题

[网络] 第一次用select,碰到问题 [复制链接]

论坛徽章:
1
2015年辞旧岁徽章
日期:2015-03-03 16:54:15
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-06-11 12:50 |只看该作者 |倒序浏览
本帖最后由 mrpre 于 2014-06-11 12:54 编辑

最简单不过的select,不知道为什么总是运行结果不是想象中的那样。

客户端:
  1.         if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(struct sockaddr)) == -1)
  2.         {
  3.                 perror("connect error\n");
  4.                 return 1;
  5.         }
  6.        
  7.         printf("connect sucess\n");
  8.        
  9.         if (send(sockfd, msg,strlen(msg), 0) == -1)
  10.         {
  11.                 printf("send error\n");
  12.                 return 1;
  13.         }  
  14.        
  15.         printf("send sucess\n");
  16.        
  17.         while(1)
  18.         {
  19.                 FD_ZERO(&readfd);
  20.                 FD_SET(sockfd,&readfd);
  21.                 if(select(sockfd+1,&readfd,NULL,NULL,NULL) > 0)
  22.                 {
  23.                         if(FD_ISSET(sockfd,&readfd))
  24.                         {
  25.                                 if ((recvbytes = recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
  26.                                 {
  27.                                         perror("recv Error!\n");     
  28.                                         return 1;
  29.                                 }
  30.                                 else
  31.                                 {
  32.                                         [b]printf("recv sucess:%s\n",buf);[/b]                                                                       
  33.                                                                     memset(buf,0,sizeof(buf));
  34.                                 }
  35.                         }
  36.                 }
  37.         }
  38.         close(sockfd);
复制代码
服务器:
  1.         while(1)
  2.         {  
  3.                 /* 服务器阻塞,直到客户程序建立连接 */
  4.                 printf("ready to accept\n");
  5.                 int sin_size = sizeof(struct sockaddr_in);   
  6.                 if ((client_fd = accept(sockfd, (struct sockaddr *)&remote_addr, &sin_size)) == -1)
  7.                 {
  8.                         //accept()函数让服务器接收客户的连接请求   
  9.                         perror("accept Error\n");     
  10.                         continue;     
  11.                 }
  12.        
  13.                 printf("received a connection from %s\n", inet_ntoa(remote_addr.sin_addr)); //inet_ntoa(将网络二进制的数字转换成网络地址)
  14.                 if ((recvbytes=recv(client_fd, buf, MAXDATASIZE, 0)) ==-1)
  15.                 {
  16.                         perror("recv Error!\n");     
  17.                         return 1;
  18.                 }
  19.        
  20.                 buf[recvbytes] = '\0';
  21.                 printf("Received: %s\n",buf);
  22.                
  23.                 if(-1 == send(client_fd,"i have received",strlen("i have received"),0))
  24.                 {       
  25.                         perror("send error\n");
  26.                         return 1;
  27.                 }

  28.                 [b]close(client_fd);[b]               
  29.         }
  30.         close(sockfd);
复制代码
当服务器加粗的语句(倒数第三行代码:close(client_fd)保留的时候:
客户端一直会打印printf("recv sucess:%s\n",buf),当然,除了第一次buf里面有数据之后,其他的结果buf都打不出数据。且不说为什么recv阻塞不阻塞
客户端的if(select(sockfd+1,&readfd,NULL,NULL,NULL) > 0)
为什么判断总是成立?服务器的的确确只发了一次数据。


当服务器加粗的语句(倒数第三行代码:close(client_fd)去除的时候:
即close(client_fd);注释掉的时候,客户端压根就没有进if(select(sockfd+1,&readfd,NULL,NULL,NULL) > 0)
可是服务器的的确确发送数据了。
可运行程序.rar (1.81 KB, 下载次数: 8)

论坛徽章:
0
2 [报告]
发表于 2014-06-16 17:59 |只看该作者
  1. if(FD_ISSET(sockfd,&readfd))
  2.                         {
  3.                                 if ((recvbytes = recv(sockfd, buf, MAXDATASIZE, 0)) ==-1)
  4.                                 {
  5.                                         perror("recv Error!\n");     
  6.                                         return 1;
  7.                                 }
  8.                                 else if(recvbytes>0)
  9.                                 {
  10.                                         printf("recv sucess:%s\n",buf);                                        //每次都能进这里
  11.                                         memset(buf,0,sizeof(buf));
  12.                                 }
  13.                                 else if(recvbytes==0)
  14.                                 {
  15.                                         printf("connect is over!\n");
  16.                                         return 0;
  17.                                 }  
  18.                         }
复制代码
你这样就可以了 close后那边接收的字节数是0

论坛徽章:
0
3 [报告]
发表于 2014-06-19 01:36 |只看该作者
我遇到更难的问题,connect函数总是block,有时候等45秒才返回,客户不知道以为死机呢。

论坛徽章:
0
4 [报告]
发表于 2014-07-02 18:46 |只看该作者
这是因为server关闭了客户端的socket之后,客户端recv返回0你没做处理,0表示对端已经关闭连接。

论坛徽章:
0
5 [报告]
发表于 2014-07-12 11:41 |只看该作者
4楼说的对。 recv返回介于区间(0,0xffffffff)之间 才表示正常接收   你客户端的代码只判断了-1的情况,没判断0的情况
man 2 recv对返回0的含义:
  These calls return the number of bytes received, or -1 if an error occurred.  The return value will be 0 when the peer has performed an orderly shutdown.

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP