0

簡単なソケット ラッパー クラスを実装しました。非ブロッキング機能が含まれています。

void Socket::set_non_blocking(const bool b) {
    mNonBlocking = b; // class member for reference elsewhere
    int opts = fcntl(m_sock, F_GETFL);
    if(opts < 0) return;
    if(b)
        opts |= O_NONBLOCK;
    else
        opts &= ~O_NONBLOCK;

    fcntl(m_sock, F_SETFL, opts);
}

このクラスには、単純な受信関数も含まれています。

int Socket::recv(std::string& s) const {
    char buffer[MAXRECV + 1];
    s = "";
    memset(buffer,0,MAXRECV+1);
    int status = ::recv(m_sock, buffer, MAXRECV,0);

    if(status == -1) {
    if(!mNonBlocking)
        std::cout << "Socket, error receiving data\n";

        return 0;
    } else if (status == 0) {
        return 0;
    } else {
        s = buffer;
        return status;
    }
}

実際には、Socket::recv() が呼び出されると、約 15 ミリ秒の遅延があるようです。この遅延は避けられますか? select() を使用するノンブロッキングの例をいくつか見たことがありますが、それがどのように役立つかわかりません。

4

4 に答える 4

1

ソケットの使用方法によって異なります。複数のソケットがあり、それらすべてをループして、遅延の原因となる可能性のあるデータをチェックしている場合。

ノンブロッキング recv を使用すると、そこにあるデータに依存します。アプリケーションで複数のソケットを使用する必要がある場合は、各ソケットを順番に常にプールして、使用可能なデータがあるかどうかを確認する必要があります。

これは、何もすることがなくてもアプリケーションが常に実行されていることを意味するため、システム リソースに悪影響を及ぼします。

select でそれを回避できます。基本的にソケットを設定し、それらをグループに追加して、グループを選択します。選択したソケットのいずれかで何かが発生すると、select は何がどのソケットで発生したかを指定して戻ります。

select の使用方法に関するコードについては、beej のネットワーク プログラミング ガイドを参照してください。

于 2009-06-25T03:13:46.973 に答える
0

あなたの大きさはどれくらいMAXRECVですか?スタックの増加でページフォールトが発生した可能性があります。受信バッファをゼロにすることは完全に不要であるとすでに述べた人もいます。std::stringまた、受信した文字データから作成するときに、メモリ割り当てとコピーヒットを取得します。

于 2009-07-21T18:15:06.363 に答える
0

select を使用すると、タイムアウトを指定でき、ソケットを読み取る準備ができているかどうかをテストできます。したがって、15ms よりも小さいものを使用できます。ちなみに、ワイヤ上のデータに埋め込まれた NUL が含まれている可能性がある場合、そのコードには注意が必要です。のようなものを使用する必要がありますs.assign(buffer, status);

于 2009-06-25T03:20:17.243 に答える
0

stefanB に加えて、毎回バッファーをゼロにしていることがわかります。なぜわざわざ?recv は、実際に読み取られたバイト数を返します。後の1バイトをゼロにするだけです( buffer[status+1]=NULL )

于 2009-06-25T03:21:23.217 に答える