免费注册 查看新帖 |

Chinaunix

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

[C] linux socket recv 出现报错resource temporarily unavailable [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-04-17 20:10 |只看该作者 |倒序浏览
本帖最后由 liyandong106 于 2011-04-17 20:19 编辑

求帮助、
  1. nrecv = recv(fd, bp, data_len, 0);
  2.                 //debug(255)("->%s\n", data);
  3.                 printf("nrecv data_count = %d\n",nrecv);
  4.                 if (nrecv == -1)
  5.                 {
  6.                         if( (errno == EAGAIN)||(errno==EWOULDBLOCK) )
  7.                         {
  8.                                 debug(255)("recv error1\n");
  9.                                 //CloseConn(channel);
  10.                                 //return -1;
  11.                                 break;
  12.                         }
  13.                         else
  14.                         {
  15.                                 debug(255)("recv error2\n");
  16.                                 CloseConn(channel);
  17.                                 return -1;
  18.                         }   
  19.                 }      
  20.                 else if (nrecv == 0 )
  21.                 {   
  22.                         CloseConn(channel);
  23.                         return -1;
  24.                 }
  25. //                data_len-=nrecv;
  26. //                bp+=nrecv;
  27. //        }

  28.                 if(virus == 1)
  29.                 {
  30.                         /*
  31.                         if(check_buf_virus(data, nrecv, "TCP PROXY") == 0)
  32.                         {
  33.                                 CloseConn(channel);
  34.                                 return -1;
  35.                         }
  36.                         */
  37.                         if(clamav_scan_buf(data_count, count_len, "TCP PROXY") == 0)
  38.                         {
  39.                                 CloseConn(channel);
  40.                                 return -1;
  41.                         }
  42.                 }
  43.                 //sleep(30);
  44.                 if(logo == 1)
  45.                 {
  46.                         printf("come in BDProtocolParse\n");
  47.                         ret = BDProtocolParse(data_count,&count_len,&struBase26Info);
  48.                         printf("ret = %d\n",ret);
  49.                        
  50.                
  51.                         total_send = 0;
  52.                         while (total_send!=count_len)
  53.                         {
  54.                                 nsend = send(other_fd, data_count+total_send, count_len-total_send, 0);
  55.                         //        nsend = send(other_fd, data_count, count_len, 0);

  56.                                 if (nsend <= 0)
  57.                                 {
  58.                                         if( errno == EAGAIN )
  59.                                         {
  60.                                                 continue;
  61.                                         }
  62.                                         perror("send");
  63.                                         CloseConn(channel);
  64.                                         return -1;
  65.                                 }
  66.                                 total_send += nsend;
  67.                         }
  68.                         printf("nsen = %d\n",nsend);
  69.                 }
  70.                 else
  71.                 {
  72.                                 //sleep(30);
  73.                         total_send = 0;
  74.                         while (total_send!=nrecv)
  75.                         {
  76.                                 nsend = send(other_fd, data_count+total_send, nrecv-total_send, 0);
  77.                                 if (nsend <= 0)
  78.                                 {
  79.                                         if( errno == EAGAIN )
  80.                                         {
  81.                                                 continue;
  82.                                         }
  83.                                         perror("send");
  84.                                         CloseConn(channel);
  85.                                         return -1;
  86.                                 }
  87.                                 total_send += nsend;
  88.                         }
  89.                         printf("nsen = %d\n",nsend);
  90.                 }
  91.                 FD_ZERO(&rfds);
  92.                 FD_SET(channel->conn_sd, &rfds);
  93.                 FD_SET(channel->server_sd, &rfds);
  94.                 sd_max = channel->conn_sd>channel->server_sd? channel->conn_sd : channel->server_sd ;

  95.                 tv.tv_sec = 2;
  96.                 tv.tv_usec = 0;

  97.                 ret = select( sd_max+1, &rfds, NULL, NULL, &tv);

  98.                 if (ret < 0)
  99.                 {
  100.                         perror("2. Select:");
  101.                         debug(1)("2. select() error\n");
  102.                         CloseConn(channel);
  103.                         return -1;
  104.                 }
  105.                 else if(ret == 0)
  106.                 {
  107.                         debug(255)("timeout\n");
  108.                         break;
  109.                 }

  110.                 if ( FD_ISSET(channel->conn_sd, &rfds) )
  111.                 {
  112.                         channel->status = ST_CLIENT_READ_READY;
  113.                 }

  114.                 if ( FD_ISSET(channel->server_sd, &rfds) )
  115.                 {
  116.                         channel->status = ST_SERVER_READ_READY;
  117.                 }

  118.         }
  119.         free(data_count);
  120.         notify.sd_local = channel->conn_sd;
  121.         notify.sd_remote = channel->server_sd;
  122.         notify.from = THREAD_WORK;
  123.         notify.context = channel->context;
  124.         move_to_spare_pool(channel);
  125.         dispatch_local_ev(notify, thread_info);

  126.         return 0;
  127. }
复制代码

论坛徽章:
0
2 [报告]
发表于 2011-04-17 20:15 |只看该作者
你是把sockfd设为了nonblock了吧?

用while循环:
while( -1 == recv() && EAGAIN != errno )

论坛徽章:
0
3 [报告]
发表于 2011-04-17 20:19 |只看该作者
回复 2# osmanthusgfy


    麻烦看一下代码 谢谢

论坛徽章:
0
4 [报告]
发表于 2011-04-17 20:24 |只看该作者
你在创建socket之后是否调用了fcntl设置sockfd为Nonblock模式?
如果是,解决办法请看之前的回复.


"resource temporarily unavailable"就是errno == EAGAIN对应的错误信息.

论坛徽章:
0
5 [报告]
发表于 2011-04-17 20:26 |只看该作者
回复 4# osmanthusgfy


    你的意思是用fctl设置成非阻塞模式?

论坛徽章:
0
6 [报告]
发表于 2011-04-17 20:28 |只看该作者
回复 2# osmanthusgfy


    但是错误是在 else
                        {
                                debug(255)("recv error2\n");
                                CloseConn(channel);
                                return -1;
                        }   里面打印出来的

论坛徽章:
0
7 [报告]
发表于 2011-04-17 20:30 |只看该作者
是的,如果sockfd设置为非阻塞模式,数据还没有发给接收端时,调用recv就会返回-1,并且errno会被设为EAGAIN.
所以你必须循环调用recv并且检测errno.

论坛徽章:
0
8 [报告]
发表于 2011-04-17 20:33 |只看该作者
回复 7# osmanthusgfy


    但是我下面有select 可以控制描述符

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
9 [报告]
发表于 2011-04-17 20:53 |只看该作者
回复  osmanthusgfy


    但是我下面有select 可以控制描述符
liyandong106 发表于 2011-04-17 20:33



    调用printf等函数都可能会改变errno的值

论坛徽章:
0
10 [报告]
发表于 2011-04-17 22:04 |只看该作者
學習學習
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP