私は奇妙な問題に直面しています。おそらく簡単ですが、ソケットに関する知識があまりないため、役に立ちません。
私はソケットプログラムを作成しましたが、別のプログラム、つまりメイン内で独立したexeとして実行すると完全に機能します。コードでわかるように、この別のプログラムで実行すると、返されるソケット fd は常に 3 です。
同じコードをコピーして、これを独自のfdが開いている別のサーバープログラムに統合すると、選択は常に0を返します。この場合、私のプログラムで作成された fd は常に 6 です。
以下の私のプログラムを参照してください。このコードに問題はありません。これが別のサーバー内で実行された場合、select は常に 0 を返します。
プログラムに既存の UDP ソケット fd がある場合、新しい UDP ソケット fd を作成できますか? ソケット fd がプログラム内で既に開かれているのとは異なる場合に、なぜこれが起こるのですか?
なぜこれが起こっているのですか、何をすべきか、または何か指針があれば教えてください。
#define MY_TIMEOUT_S 5
int mySock;
if ((mySock = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
perror("Cannot create UDP socket");
return -1;
}
struct sockaddr_in myAddr;
myAddr.sin_family = AF_INET;
myAddr.sin_port = 0;
myAddr.sin_addr.s_addr = INADDR_ANY;
memset(&(myAddr.sin_zero), '\0', 8);
if (bind(mySock, (struct sockaddr*)&myAddr,
sizeof(struct sockaddr)) == -1) {
perror("Cannot bind UDP socket to desired port");
close(mySock);
return -1;
}
// here send to remote target host on udp socket and port
char buf[MAX_UDP_PACKET_SIZE];
struct sockaddr_in theirAddr;
int addrLen = sizeof(struct sockaddr);
fd_set readSet, curReadSet;
FD_ZERO(&readSet);
FD_SET(mySock, &readSet);
int maxFD = mySock;
while (true) {
struct timeval timeOutTV = {MY_TIMEOUT_S, 0};
memcpy(&curReadSet, &readSet, sizeof(fd_set));
int selectRet = select(maxFD+1, &curReadSet, NULL, NULL, &timeOutTV);
cout<<"select value =" <<selectRet<<endl;
if (selectRet == -1) {
if (errno == EINTR) {
continue; // Interrupted by signal, retry
}
close(mySock);
return -1;
} else if (selectRet == 0) {
close(mySock);
return -1;
}
if (FD_ISSET(mySock, &curReadSet)) {
int numBytes = recvfrom(mySock, buf, MAX_UDP_PACKET_SIZE, 0,
(struct sockaddr*)&theirAddr, (socklen_t*)&addrLen);
if (numBytes == -1) {
close(mySock);
}
}
}
lsof 出力からの詳細の追加
1)これは、データを送信する必要があるターゲットです sudo lsof -a -p 16061
target 16061 root 3r FIFO 0,8 0t0 153467 pipe
target 16061 root 4u IPv4 153470 0t0 UDP *:3290
target 16061 root 5u sock 0,6 0t0 153471 can't identify protocol
target 16061 root 6u IPv4 153472 0t0 TCP *:3290 (LISTEN )
ターゲット 16061 ルート 7u 生 0t0 153473 00000000:0001->00000000:0000 st=07
2)これは、別のexeで実行した場合の上記のコードです。FD = 3が正常に機能するため、メイン内で実行されるコードはこれだけです
sudo lsof -a -p 16112
myProg 16112 ルート 0u CHR 136,4 0t0 7 /dev/pts/4
myProg 16112 ルート 1u CHR 136,4 0t0 7 /dev/pts/4
myProg 16112 ルート 2u CHR 136,4 0t0 7 /dev/pts/4
myProg 16112ルート 3u IPv4 153564 0t0 UDP *:60503
3)これは、独立して動作している上記の同じコードを統合したWebサーバーですが、現在はそうではありません
これは、実行中の私のWebサーバーの出力です
webServ 18431 ルート 3u unix 0xc09f9b00 0t0 157975 ソケット
webServ 18431 ルート 4u IPv4 157976 0t0 UDP *:8080
webServ 18431 ルート 5u IPv4 157977 0t0 TCP *:8080 (リッスン)
今、私はリクエストを送信し、サーバー側で新しい統合コードが実行され、無限ループを配置し、lsof出力を表示するためだけにソケットを閉じませんでした
4) 統合後の出力
webServ 18449 ルート 3u unix 0xc09f9b00 0t0 157975 ソケット
webServ 18449 ルート 4u IPv4 157976 0t0 UDP *:8080
webServ 18449 ルート 5u IPv4 157977 0t0 TCP *:8080 (リッスン)
webServ 18449 ルート 6u IPv4 15805 U7 *4
唯一の違いは、サーバーに統合されている場合、ソケット FD が異なることです。それが唯一の違いです。
これが私の質問に答えるのに役立つことを願っています。
なぜこれが起こっているのかわかりません。助けてください