select:windows pipeのシミュレーション
2078 ワード
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/uid-736168-id-375914.html)では、著者らはwindows上でパイプをシミュレートする方法を提供したが、欠点も明らかで、詳細は原文を参照し、コードは以下の通りである.
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/uid-736168-id-375914.html)では、著者らはwindows上でパイプをシミュレートする方法を提供したが、欠点も明らかで、詳細は原文を参照し、コードは以下の通りである.
int pipe(int fildes[2])
{
int tcp1, tcp2;
sockaddr_in name;
memset(&name, 0, sizeof(name));
name.sin_family = AF_INET;
name.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
int namelen = sizeof(name);
tcp1 = tcp2 = -1;
int tcp = socket(AF_INET, SOCK_STREAM, 0);
if (tcp == -1){
goto clean;
}
if (bind(tcp, (sockaddr*)&name, namelen) == -1){
goto clean;
}
if (listen(tcp, 5) == -1){
goto clean;
}
if (getsockname(tcp, (sockaddr*)&name, &namelen) == -1){
goto clean;
}
tcp1 = socket(AF_INET, SOCK_STREAM, 0);
if (tcp1 == -1){
goto clean;
}
if (-1 == connect(tcp1, (sockaddr*)&name, namelen)){
goto clean;
}
tcp2 = accept(tcp, (sockaddr*)&name, &namelen);
if (tcp2 == -1){
goto clean;
}
if (closesocket(tcp) == -1){
goto clean;
}
fildes[0] = tcp1;
fildes[1] = tcp2;
return 0;
clean:
if (tcp != -1){
closesocket(tcp);
}
if (tcp2 != -1){
closesocket(tcp2);
}
if (tcp1 != -1){
closesocket(tcp1);
}
return -1;
}