3

ねえ、私はrecv()でこの奇妙な問題を抱えています。私はクライアント/サーバーをプログラミングしており、クライアントはメッセージ(正確には構造)をsend()し、サーバーはそれをrecv()します。また、複数のソケットとselect()を使用しています。

while(1)
{
    readset = info->read_set;
    info->copy_set = info->read_set;

    timeout.tv_sec = 1; 
    timeout.tv_usec = 0; // 0.5 seconds

    ready = select(info->max_fd+1, &readset, NULL, NULL, &timeout);

    if (ready == -1)
    {
        printf("S: ERROR: select(): %s\nEXITING...", strerror(errno));
        exit(1);
    }
    else if (ready == 0)
    {
        continue;
    }
    else
    {
        printf("S: oh finally you have contacted me!\n");
        for(i = 0; i < (info->max_fd+1); i++)
        {

            if(FD_ISSET(i, &readset)) //this is where problem begins
            {
                printf("S: %i is set\n", i);
                printf("S: we talking about socket %i son\n", i);  // i = 4
                num_bytes = recv(i, &msg, MAX_MSG_BYTE, 0);
                printf("S: number of bytes recieved in socket %i is %i\n", i, num_bytes); // prints out i = 0 what??

                if (num_bytes == 0)
                {
                    printf("S: socket has been closed\n");
                    break;
                }
                else if (num_bytes == -1)
                {
                    printf("S: ERROR recv: %d %s \n", i, strerror(errno));
                    continue;
                }
                else                    
                {
                    handle_request(arg, &msg);
                    printf("S: msg says %s\n", msg->_payload);
                }
            } // if (FD_ISSET(i, &readset)
            else
                printf("S:  %i is not set\n", i);
        } // for (i = 0; i < maxfd+1; i++) to check sockets for msg
    } // if (ready == -1)   

    info->read_set = info->copy_set;
    printf("S: copied\n");

} 

私が抱えている問題は、ではread_set、0〜3が設定されておらず、4が設定されていることです。それは結構です。しかし、電話recv()をかけると、i突然0になります。それはなぜですか。recv()なぜソケットファイル記述子番号を取得して別の番号に変更するのか、私には意味がありません。それは正常ですか?私は何かが足りないのですか?

S:  0 is not set
S:  1 is not set
S:  2 is not set
S:  3 is not set
S: 4 is set
S: we talking about socket 4 son
S: i is strangely or unstrangely 0
S: number of bytes recieved in socket 0 is 40

それが印刷されます。

4

2 に答える 2

2

recv最初の引数は値によって取得されるため、変更できません。

msgまたはを宣言した場所は表示されませんがi、この行に基づいています

printf("S: msg says %s\n", msg->_payload);

->演算子 onを使用する場合、msgおそらく次のようになると思います。

struct somestruct* msg = malloc(sizeof(struct somestruct));
int i;

次に、これを行います。

num_bytes = recv(i, &msg, MAX_MSG_BYTE, 0);

msgすでにポインターである&msgことに注意してください。ポインターへのポインターでもあります

これが次に行うことは、データを受け取り、 を指す場所ではなく、msg ポインタ自体がある場所に格納しようとすることです。通常、ポインターの長さは 4 バイトしかないため、4 バイトを超えると、ストレージがオーバーフローします。の後にスタックで が宣言されている場合、このオーバーフローによって上書きされている可能性が高く、受信したパケットのすべてのゼロ バイトによってたまたま上書きされます。msgimsg

は既にポインターであるためmsg、受信行を変更して余分な間接指定を削除します。

num_bytes = recv(i, msg, MAX_MSG_BYTE, 0);

同様に、行に同じ変更を加えることを検討したい場合があります

handle_request(arg, &msg)

handle_request関数がポインターからポインターを実際に期待していない場合。

于 2010-04-20T00:29:06.167 に答える
1

私の最初の推測はそれでsizeof(msg) < MAX_MSG_BYTEあり、recvオーバーフローmsgするとそれは破棄されiます。

于 2010-04-20T00:22:23.963 に答える