0

ブロッキング ソケット サーバーを非ブロッキング バージョンに書き換える際に問題が発生しています。実際、私はもうソケットを接続することさえできないようです.私は今日のほとんどをグーグルで検索し、あちこちで見つけたさまざまな解決策を試しましたが、どれも正しく機能していないようです...現在、私のサーバーループ新しいソケットが受け入れられずに、select() 呼び出しをタイムアウトし続けるだけです。クライアントソケットは、開始すると書き込みをブロックし、サーバーを閉じると接続がピアによってリセットされたことを通知するため、何らかのレベルで接続しているようです。

次の仮定は正しいですか?ノンブロッキングサーバーでは、通常、ソケットを開き、フラグをノンブロッキングに設定してバインドし、読み取りファイル記述子の選択の呼び出しを開始して、それが読み込まれるのを待つ必要がありますか? 無限に待っていた古いブロッキング「accept()」呼び出しを削除する必要があります..accept を呼び出そうとすると、-1 になります...

ここに私が今試している関連コードがあります

fd_set incoming_sockets;
....
int listener_socket, newsockfd, portno;
socklen_t clilen;
struct sockaddr_in serv_addr, cli_addr;
....
listener_socket = socket(AF_INET, SOCK_STREAM, 0); //get socket handle
int flags = fcntl(listener_socket, F_GETFL, 0);
if( fcntl(listener_socket, F_SETFL, flags | O_NONBLOCK) < 0 )
    log_writer->write_to_error_log("Error setting listening socket to non blocking", false);
memset(&serv_addr, 0, sizeof(struct sockaddr_in));

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons(portno);
....
if (bind(listener_socket, (struct sockaddr *) &serv_addr,
        sizeof(struct sockaddr_in)) < 0)
{
    log_writer->write_to_error_log("Unable to bind socket, aborting!", true);
}
....
struct timeval timeout;
timeout.tv_sec = 1;
timeout.tv_usec = 0;

int ready_sockets = 0;

listen(listener_socket,1);

FD_ZERO(&incoming_sockets); 
FD_SET(listener_socket, &incoming_sockets); 

while(true)
{

ready_sockets = select(listener_socket + 1 , &incoming_sockets, (fd_set * ) 0, (fd_set * ) 0, &timeout  );

if(ready_sockets == 0)
    {
        //I loop here now for ever
        std::cout << "no new sockets available, snooze 2\n";
        sleep(2);
    } else
    {
    std::cout << "connection received!\n";
4

2 に答える 2

1

ループ全体を示していないため、後で行うかどうかはわかりませんが、を呼び出すたびに記述子セットとタイムアウト構造を初期化する必要がありますselect

于 2012-01-17T09:34:06.293 に答える
0

ループ内でfd_zero()fd_set()マクロを移動する必要があります。選択すると、fd_sets(およびタイムアウト値)のビットマスクが実際に変更されます。反復ごとにそれらを再初期化します。また、select return -1および関連するerrno(EPIPE ...)を確認します。

while(true)
{

FD_ZERO(&incoming_sockets); 
FD_SET(listener_socket, &incoming_sockets); 



ready_sockets = select(listener_socket + 1 , &incoming_sockets, (fd_set * ) 0, (fd_set * ) 0, &timeout  );

if(ready_sockets == 0)
    {
      ... }
于 2012-01-17T09:43:55.503 に答える