免费注册 查看新帖 |

Chinaunix

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

[网络] socket select 问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2012-08-08 10:44 |只看该作者 |倒序浏览
我在  客户端 ,与 服务端 都设置了 select(),  一个监听可读  一个监听可写
client — select(sockId, NULL,fdset,NULL,&timeOut); (timeOut 设置超时时间) 监听可写
server — select(workersock,fdset,NULL.NULL,NULL) (timeout 设置为NULL,持续等待数据) 监听可读

为什么   server端 阻塞在了select  ,  直到  client 端 超时 重连后 才能读到数据。?
希望大牛 给点指示。

论坛徽章:
0
2 [报告]
发表于 2012-08-08 23:16 |只看该作者
建议你看看
  1. int select(int nfds, fd_set *readfds, fd_set *writefds,
  2.                   fd_set *exceptfds, struct timeval *timeout);
复制代码
nfds is the highest-numbered file descriptor in any of the three sets, plus 1.

论坛徽章:
0
3 [报告]
发表于 2012-08-08 23:54 |只看该作者
回复 2# xiyoulaoyuanjia


嗯 这个+1 了,似乎不是这里的问题,在判断可读 可写时,总是 阻塞在哪里,直到timeOut  后 第一次连接才有数据。

论坛徽章:
0
4 [报告]
发表于 2012-08-09 10:14 |只看该作者
把代码贴出来看看吧~

论坛徽章:
0
5 [报告]
发表于 2012-08-09 16:31 |只看该作者
//这是客户端
  1. while (1)
  2.     {
  3.         struct in_addr              addr;
  4.         char *                      serverIpStr;
  5.         char *                      tmpPort;
  6.         int                         initFlag = 1;
  7.         status = 0;
  8.         timeOutCount = 0;

  9.         if(sockId >= 0){
  10.             safeclose(sockId);
  11.             sockId = -1;
  12.             sleep(1);
  13.         }

  14.         serverIpStr = ipSever;
  15.         tmpPort     = Port;

  16.         for(count = 0; count < 3; count++){
  17.             sockId = clientconnect(serverIpStr,tmpPort,Proto);

  18.             printf("sockId: %d\n",sockId);
  19.             if(sockId >= 0) break;
  20.             sleep(1);
  21.         }
  22.         if(sockId < 0){
  23.             printf("fail,connect ip is %s,port id %s,try times is %d NOW GO TO  TRY_OTHER",serverIpStr,tmpPort,count);
  24.             continue;
  25.         }

  26.         printf("success,connect ip :%s,port %s,sockId %d\n",serverIpStr,tmpPort,sockId);

  27.         FD_ZERO(&oriSelectSet);
  28.         FD_SET(sockId,&oriSelectSet);
  29.         do{
  30.                 read_size = readRingShm(sem_id,shm_buff,cTemp,&read_count);
  31.         }while(!read_size);

  32.         while(initFlag){
  33.             memcpy(&selectSet,&oriSelectSet,sizeof(selectSet));
  34.             timeOut.tv_sec = 3;
  35.             timeOut.tv_sec = 3;
  36.             timeOut.tv_usec = 0;

  37.             selectRvalue = select(sockId+1,NULL,&selectSet,NULL,&timeOut);

  38.             if(selectRvalue > 0){
  39.                 timeOutCount = 0;
  40.                 if(FD_ISSET(sockId,&selectSet)){//success
  41.                     send_size = 0;
  42.                     send_count = 0;
  43.                 //  do{
  44.                         read_size = readRingShm(sem_id,shm_buff,cTemp,&read_count);
  45.                 //   }while(!read_size);
  46.             //printf("read_size:%d\n",read_size);

  47.                 //char str[10];

  48.                 //memset(cTemp,sui,CARD_DATA_SIZE);
  49.                  //sui++;
  50.                     /*
  51.                     while(1){
  52.                             i_left =  read_size - send_count;
  53.                             if(i_left <= 0)
  54.                             break;
  55.                             send_size = write_buffer_send(sockId,cTemp+send_count,i_left,25);
  56.                            
  57.                             if(send_size < 0){
  58.                                 printf("send fail \n");
  59.                             }else if(0 == send_size){
  60.                            
  61.                                 printf("send time out\n");
  62.                                 usleep(2000);
  63.                             }else{
  64.                                 send_count += send_size;
  65.                                 if(send_count  == CARD_DATA_SIZE){
  66.                                     break;
  67.                                 }
  68.                            
  69.                             }
  70.                         */
  71.                             send(sockId,cTemp,CARD_DATA_SIZE,0);
  72.                     //}
  73.                   close(sockId);
  74.                 }
  75.             }else if(selectRvalue == 0){


  76.             //timeOut
  77.                 //sleep(2);
  78.                 if(++timeOutCount >= TIMEOUT){
  79.                     printf("time out\n");
  80.                     initFlag = 0;
  81.                 }
  82.                 FD_CLR(sockId,&oriSelectSet);
  83.                 continue;
  84.             }else{
  85.             // system error
  86.                 if(errno != EINTR)
  87.                 printf("error sockId :%d",sockId);
  88.                 initFlag =0;
  89.                 //sleep(2);
  90.                 FD_CLR(sockId,&oriSelectSet);
  91.                 continue;
  92.             }
  93.         }

  94.     }
复制代码

论坛徽章:
0
6 [报告]
发表于 2012-08-09 16:33 |只看该作者
这是服务端
  1. while(1){
  2.         bcopy(&orig_fdset,&fdset,sizeof(orig_fdset));
  3.         timeOut.tv_sec = tvLimit.tv_sec - tvCurr.tv_sec;
  4.         timeOut.tv_usec = 0;
  5.         printf("select ....\n");
  6.         selectVal = select(mastersock+1,&fdset,NULL,NULL,0);

  7.         if(selectVal > 0){
  8.             if(FD_ISSET(mastersock,&fdset)){
  9.                 workersock = accept(mastersock,(struct sockaddr *)&socketaddr,(socklen_t *)&addrlen);

  10.                 if(workersock > 0){
  11.                     int result = recv(workersock,cefBuff,CARD_DATA_SIZE,0);
  12.                     printf("result :%d\n",result);
  13.                     if(result){
  14.                         memcpy(cMiddleBuff+lMiddLen,cefBuff,result);
  15.                         lMiddLen += result;
  16.                         if(lMiddLen > CARD_DATA_SIZE){
  17.                             printf("do\n");
  18.                               do{
  19.                                 iWriteCacheSuccess = writeRingShm(semId[pchannel->cardid],buffer[pchannel->cardid],
  20.                                                     (char *)cMiddleBuff,CARD_DATA_SIZE);
  21.                                 }while(0 == iWriteCacheSuccess);
  22.                                 memcpy(cTemp,cMiddleBuff+CARD_DATA_SIZE,lMiddLen - CARD_DATA_SIZE);
  23.                                 memcpy(cMiddleBuff,cTemp,lMiddLen - CARD_DATA_SIZE);
  24.                                 lMiddLen -= CARD_DATA_SIZE;
  25.                         }
  26.                         //close(workersock);
  27.                      }else{
  28.                         printf("recive server's data error\n");
  29.                         continue;
  30.                      }
  31.                     //close(workersock);
  32.                 }
  33.              // FD_SET(workersock,&orig_fdset);
  34.             }
  35.        }else if(0 == selectVal){
  36.             printf("waring :select  rerturn 0");\
  37.             continue;
  38.        }else{
  39.             printf("error:select return error\n");
  40. }
  41. }
复制代码
麻烦给点指点

论坛徽章:
0
7 [报告]
发表于 2012-08-09 16:33 |只看该作者
回复 4# xiyoulaoyuanjia
麻烦给看下

   

论坛徽章:
0
8 [报告]
发表于 2012-08-09 16:37 |只看该作者
本帖最后由 liuchang8877 于 2012-08-09 18:24 编辑

客户端的 connect
  1. int clientconnect(const char *host, const char *port, const char *proto)
  2. {
  3.     int sockid = -1;
  4.     int nProto = resolveproto(proto);
  5.     if(nProto == 17)
  6.     {
  7.         sockid = serverinit(port, proto);
  8.     }
  9.     else
  10.     {
  11.         unsigned long non_blocking = 1;
  12.         unsigned long blocking = 0;
  13.         struct sockaddr_in socketaddr;
  14.         socketaddr_init(&socketaddr);
  15.         socketaddr_service(&socketaddr, port, proto);
  16.         socketaddr_host(&socketaddr, host);
  17.         sockid = socket(PF_INET, prototype(proto), nProto);
  18.         if (sockid < 0)
  19.         {
  20.             //HandleError(errno, "clientconnect", "socket failed");
  21.             return -1;
  22.         }   
  23.             
  24.         ioctl(sockid,FIONBIO,&non_blocking);
  25.         if (connect(sockid, (struct sockaddr *)&socketaddr, sizeof(socketaddr)) == -1){
  26.             struct timeval tv;
  27.             fd_set writefds;
  28.             int error;
  29.    
  30.             tv.tv_sec = 3;
  31.             tv.tv_usec = 0;
  32.             FD_ZERO(&writefds);
  33.             FD_SET(sockid, &writefds);
  34.             if(select(sockid+1,NULL,&writefds,NULL,&tv) != 0){
  35.                 if(FD_ISSET(sockid,&writefds)){
  36.                     int len=sizeof(error);
  37.                     if(getsockopt(sockid, SOL_SOCKET, SO_ERROR,  (char *)&error,(unsigned int *)&len) < 0)
  38.                         goto error_ret;
  39.                     if(error != 0)
  40.                         goto error_ret;
  41.                 }
  42.               else
  43.                     goto error_ret; //timeout or error happen
  44.             }
  45.             else goto error_ret; ;
  46.             ioctl(sockid,FIONBIO,&blocking);
  47.         }
  48.         else
  49.         {
  50. error_ret:
  51.             safeclose(sockid);
  52.             return -1;
  53.         }
  54.     }
  55.     return sockid;
  56. }


复制代码

论坛徽章:
0
9 [报告]
发表于 2012-08-10 09:42 |只看该作者
dingqi

论坛徽章:
0
10 [报告]
发表于 2012-08-11 11:10 |只看该作者
这个是完整的吗? 而且不写注释看得我头疼~~
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP