linux socket recv 出现报错resource temporarily unavailable
本帖最后由 liyandong106 于 2011-04-17 20:19 编辑
求帮助、
- nrecv = recv(fd, bp, data_len, 0);
- //debug(255)("->%s\n", data);
- printf("nrecv data_count = %d\n",nrecv);
- if (nrecv == -1)
- {
- if( (errno == EAGAIN)||(errno==EWOULDBLOCK) )
- {
- debug(255)("recv error1\n");
- //CloseConn(channel);
- //return -1;
- break;
- }
- else
- {
- debug(255)("recv error2\n");
- CloseConn(channel);
- return -1;
- }
- }
- else if (nrecv == 0 )
- {
- CloseConn(channel);
- return -1;
- }
- // data_len-=nrecv;
- // bp+=nrecv;
- // }
- if(virus == 1)
- {
- /*
- if(check_buf_virus(data, nrecv, "TCP PROXY") == 0)
- {
- CloseConn(channel);
- return -1;
- }
- */
- if(clamav_scan_buf(data_count, count_len, "TCP PROXY") == 0)
- {
- CloseConn(channel);
- return -1;
- }
- }
- //sleep(30);
- if(logo == 1)
- {
- printf("come in BDProtocolParse\n");
- ret = BDProtocolParse(data_count,&count_len,&struBase26Info);
- printf("ret = %d\n",ret);
- total_send = 0;
- while (total_send!=count_len)
- {
- nsend = send(other_fd, data_count+total_send, count_len-total_send, 0);
- // nsend = send(other_fd, data_count, count_len, 0);
- if (nsend <= 0)
- {
- if( errno == EAGAIN )
- {
- continue;
- }
- perror("send");
- CloseConn(channel);
- return -1;
- }
- total_send += nsend;
- }
- printf("nsen = %d\n",nsend);
- }
- else
- {
- //sleep(30);
- total_send = 0;
- while (total_send!=nrecv)
- {
- nsend = send(other_fd, data_count+total_send, nrecv-total_send, 0);
- if (nsend <= 0)
- {
- if( errno == EAGAIN )
- {
- continue;
- }
- perror("send");
- CloseConn(channel);
- return -1;
- }
- total_send += nsend;
- }
- printf("nsen = %d\n",nsend);
- }
- FD_ZERO(&rfds);
- FD_SET(channel->conn_sd, &rfds);
- FD_SET(channel->server_sd, &rfds);
- sd_max = channel->conn_sd>channel->server_sd? channel->conn_sd : channel->server_sd ;
- tv.tv_sec = 2;
- tv.tv_usec = 0;
- ret = select( sd_max+1, &rfds, NULL, NULL, &tv);
- if (ret < 0)
- {
- perror("2. Select:");
- debug(1)("2. select() error\n");
- CloseConn(channel);
- return -1;
- }
- else if(ret == 0)
- {
- debug(255)("timeout\n");
- break;
- }
- if ( FD_ISSET(channel->conn_sd, &rfds) )
- {
- channel->status = ST_CLIENT_READ_READY;
- }
- if ( FD_ISSET(channel->server_sd, &rfds) )
- {
- channel->status = ST_SERVER_READ_READY;
- }
- }
- free(data_count);
- notify.sd_local = channel->conn_sd;
- notify.sd_remote = channel->server_sd;
- notify.from = THREAD_WORK;
- notify.context = channel->context;
- move_to_spare_pool(channel);
- dispatch_local_ev(notify, thread_info);
- return 0;
- }
复制代码
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
你是把sockfd设为了nonblock了吧?
用while循环:
while( -1 == recv() && EAGAIN != errno )
回复 2# osmanthusgfy
麻烦看一下代码 谢谢
你在创建socket之后是否调用了fcntl设置sockfd为Nonblock模式?
如果是,解决办法请看之前的回复.
"resource temporarily unavailable"就是errno == EAGAIN对应的错误信息.
回复 4# osmanthusgfy
你的意思是用fctl设置成非阻塞模式?
回复 2# osmanthusgfy
但是错误是在 else
{
debug(255)("recv error2\n");
CloseConn(channel);
return -1;
} 里面打印出来的
是的,如果sockfd设置为非阻塞模式,数据还没有发给接收端时,调用recv就会返回-1,并且errno会被设为EAGAIN.
所以你必须循环调用recv并且检测errno.
回复 7# osmanthusgfy
但是我下面有select 可以控制描述符
调用printf等函数都可能会改变errno的值
學習學習