windows select pipe

来源:互联网 发布:赚钱宝监控软件 编辑:程序博客网 时间:2024/05/17 06:47

转载自:http://blog.csdn.net/chief1985/article/details/5064998

在进行socket编程时,经常会采用select或epoll来接受并发请求。在有些系统里面(例如嵌入式设备),是不支持epoll的,这时只能用select。

Select定义如下:
int select(int n, fd_set *rd_fds, fd_set *wr_fds, fd_set *ex_fds, struct timeval *timeout);

在进行select的时候,如果等待的句柄没有发生变化和没有超时,select是会一直等待在那里的。但在某些情况下,你需要唤醒select,你会怎么办呢?在linux上,你可以将管道的句柄传给select,然后在要唤醒select的时候向管道里面写东西就可以了(palm pre手机里面就用了这种技巧,我是通过反汇编知道的)。但在windows平台下,你就不能将管道传给select了,这时你就需要用socket来模拟管道了。在windows pipe的模拟(http://blog.chinaunix.net/u2/69656/showart_705924.html)里面,作者提供了一种在windows上模拟管道的方法,代码如下:

 

[cpp] view plain copy
  1. int pipe(int fildes[2])  
  2. {  
  3.     int tcp1, tcp2;  
  4.     sockaddr_in name;  
  5.     memset(&name, 0, sizeof(name));  
  6.     name.sin_family = AF_INET;  
  7.     name.sin_addr.s_addr = htonl(INADDR_LOOPBACK);  
  8.     int namelen = sizeof(name);  
  9.     tcp1 = tcp2 = -1;  
  10.     int tcp = socket(AF_INET, SOCK_STREAM, 0);  
  11.     if (tcp == -1){  
  12.         goto clean;  
  13.     }  
  14.     if (bind(tcp, (sockaddr*)&name, namelen) == -1){  
  15.         goto clean;  
  16.     }  
  17.     if (listen(tcp, 5) == -1){  
  18.         goto clean;  
  19.     }  
  20.     if (getsockname(tcp, (sockaddr*)&name, &namelen) == -1){  
  21.         goto clean;  
  22.     }  
  23.     tcp1 = socket(AF_INET, SOCK_STREAM, 0);  
  24.     if (tcp1 == -1){  
  25.         goto clean;  
  26.     }  
  27.     if (-1 == connect(tcp1, (sockaddr*)&name, namelen)){  
  28.         goto clean;  
  29.     }  
  30.     tcp2 = accept(tcp, (sockaddr*)&name, &namelen);  
  31.     if (tcp2 == -1){  
  32.         goto clean;  
  33.     }  
  34.     if (closesocket(tcp) == -1){  
  35.         goto clean;  
  36.     }  
  37.     fildes[0] = tcp1;  
  38.     fildes[1] = tcp2;  
  39.     return 0;  
  40. clean:  
  41.     if (tcp != -1){  
  42.         closesocket(tcp);  
  43.     }  
  44.     if (tcp2 != -1){  
  45.         closesocket(tcp2);  
  46.     }  
  47.     if (tcp1 != -1){  
  48.         closesocket(tcp1);  
  49.     }  
  50.     return -1;  
  51. }  
 

在这段代码里面,有一个技巧是:将port设为0,然后进行bind,再接着通过getsockname来获取port。这可以满足获取随机端口的情况。

0 0
原创粉丝点击