1

同じ IP (10080、20081、30082) からの異なるポートをリッスンする 3 つのソケットがあります。さまざまなスレッド (実際には pthreads) でソケットを作成し、それをバインドしました。Accept() を実行すると、3 つのソケットがクライアント呼び出しを待機しますが、任意のポートの呼び出しを実行すると、常に最後の Accept() を作成するソケットに応答します。

それが私のプロセスです(C ++):

スレッド 1

ポート 10080 のソケットを作成します

ポート 10080 のバインド ソケット

ポート 10080 をリッスンする

ポート 10080 を受け入れる

................................................................... ...................................

スレッド 2

ポート 20081 用のソケットを作成します

ポート 20081 のバインド ソケット

ポート 20081 をリッスンする

ポート 20081 を受け入れる

................................................................... ...................................

スレッド 3

ポート 30082 のソケットを作成します

ポート 30082 のバインド ソケット

ポート 30082 をリッスンする

ポート 30082 を受け入れる

................................................................... ...................................

どのポート (10080、20081、または 30082) を呼び出しているかに関係なく、常に「スレッド 3」の処理が続行されます。

正しいスレッドで情報を処理するのを手伝ってくれる人はいますか?

ありがとう。

PS: メイン ソケットにあるポートと、Accept() 命令によって作成されたソケットにあるポートを監視していますが、メイン ソケットはまだ正しく (30082)、Accept ソケットには呼び出されたポート (10080、20081、または 30082) があります。 )。

struct addrinfo lRequestAddrInfo;
struct addrinfo * lResultAddrInfo;
int lSocketOption = 1;

memset(&lRequestAddrInfo,0,sizeof(lRequestAddrInfo));
lRequestAddrInfo.ai_socktype=SOCK_STREAM;
lRequestAddrInfo.ai_flags=AI_PASSIVE;
int lReturn = 0;

lReturn = getaddrinfo(lAddress->ip.c_str(), lAddress->port.c_str(), &lRequestAddrInfo, &lResultAddrInfo);

int lSocket = socket(lResultAddrInfo->ai_family, SOCK_STREAM, lResultAddrInfo->ai_protocol);
setsockopt(lSocket, SOL_SOCKET, SO_REUSEADDR, &lSocketOption, sizeof(lSocketOption));
lReturn = bind(lSocket, lResultAddrInfo->ai_addr, lResultAddrInfo->ai_addrlen);
lReturn = listen(lSocket, SOMAXCONN);
while(IsConnected())
{
    struct sockaddr lSocketAddress;
    socklen_t lSocketAddresslen = sizeof(lSocketAddress);
    lNewSocket = accept(pListener->_connection, &lSocketAddress, &lSocketAddresslen);

    if (lNewSocket > -1)
    {
        //process information in new thread
    }   
}

これはスレッド内のコードです。より詳しい情報:

スレッド 1

lソケット = 3 (ポート 10080)

スレッド 2

lSocket = 5 (ポート 20081)

スレッド 3

lSocket = 7 (ポート 30082)

ポート10080で呼び出すと

lSocket = 7 (ポート 30082) lNewSocket = 4 (ポート 10080)

ポート20081で呼び出すと

lSocket = 7 (ポート 30082) lNewSocket = 6 (ポート 20081)

ポート30082で呼び出すと

lSocket = 7 (ポート 30082) lNewSocket = 8 (ポート 30082)

4

2 に答える 2

0

コードの重要な部分が欠けていると思います。含めなかったので、FD_SET()、FD_ISSET()、およびその仲間をまったく使用しているかどうかを判断するのは困難です。そうでない場合は、奇妙な結果が得られます。言葉で説明するよりもコードを貼り付けた方が簡単だと思います。これは私にとって同様のことがどのように機能するかです:

socket_descriptor=bindsock(thd);
while(true) {
        fd_set      rfs, wfs;
        FD_ZERO(&rfs);
        FD_ZERO(&wfs);

        FD_SET(socket_descriptor,&rfs);
        maxfd = conn_select(thd,&rfs, &wfs);

        if (select(maxfd + 1, &rfs, &wfs, NULL, NULL) == -1) {
            if (errno == EINTR) {
                continue;
            }
            break;
        }
        if (FD_ISSET(socket_descriptor, &rfs)) {
            thd->client_fd = accept(socket_descriptor, &thd->cliaddr,&clilen);

....

そして関数の内部:

int
conn_select(struct THD*thd,fd_set * rfs, fd_set * wfs) {
    int maxfd = -1;
    size_t i;
    DBUG_ENTER("conn_cullselect");

    if (vector == NULL) {
        DBUG_PRINT("info",("vector == NULL"));
        DBUG_RETURN(0);
    }

    for (i = 0; i < MAX_CONNECTIONS; i++) {
        conn_t     *v;

        if (vector[i] == NULL) {
            DBUG_PRINT("info",("continue"));
            continue;
        }
        v = vector[i];
        switch (v->state) {
            case AWAITING_REQUEST:
                DBUG_PRINT("info",("AWAITING_REQUEST"));
                if (maxfd < v->sd) {
                    maxfd = v->sd;
                }
                FD_SET(v->sd, rfs);
                break;
            case SENDING_FILE:
                DBUG_PRINT("info",("SENDING_FILE"));
                if (maxfd < v->fd) {
                    maxfd = v->fd;
                }
                FD_SET(v->fd, rfs);
                break;
            case SENDING_HEADER:
                DBUG_PRINT("info",("SENDING_HEADER"));
                if (maxfd < v->sd) {
                    maxfd = v->sd;
                }
                FD_SET(v->sd, wfs);
                break;
        }
    }
    DBUG_PRINT("info",("returning %d from conn_cullselect",maxfd));
    DBUG_RETURN(maxfd);
}

リッスンしているポートの数に関係なく、アイデアは同じです。

于 2012-06-08T09:12:23.490 に答える
0

最後に私はやった!ソケットの作成とリッスン アクションはスレッドの外側に記述し、受け入れアクションはスレッドの内側に記述しました。

これが他の人に役立つことを願っています!

答えてくれてありがとう!

于 2012-06-12T10:26:38.337 に答える