3

送信バッファがいっぱいになったときに書き込みが失敗するかブロックされるかを証明するために、実験的なクライアント/サーバー プログラムを作成しようとしています。基本的に、送信側プログラムに無限ループがあり、 select() を使用してバッファーに書き込めるかどうかを確認します (これは、ソケットバッファーがいっぱいではないことを意味します)。文字を write() します。FD_ISSET(sockfd, &writefds) が false の場合、ループが中断されます (バッファーがいっぱいであるため、バッファーに書き込むことができません)。受信側プログラムは、read() を開始する前に 1 分間スリープします。このスリープ時間内に送信者がバッファをいっぱいにすることを期待していますが、実際には、プログラムは決して終了しません。

差出人:

int main(int argc, char *argv[]) {
    char buffer[100];
    int sockfd, total = 0, bytes = 0;
    fd_set writefds;

    sockfd = dial(argv[1], argv[2]);
    bzero(buffer, sizeof buffer);

    while(1)
    {
        int ret = 0;
        FD_ZERO(&writefds);
        FD_SET(sockfd, &writefds);

        if((ret = select(sockfd + 1, NULL, &writefds, NULL, 0)) < 0)
        {
            perror("select");
            exit(errno);
        }

        if(FD_ISSET(sockfd, &writefds))
        {
            write(sockfd, "a", 1);
            total++;
            continue;
        }
        else
        {
            puts("I can't write in the socket buffer");
            break;
        }
    }
    printf("nb chars written: %d\n", total);

    return 0;
}

レシーバー:

int foo(int sockfd) {
    char buffer[100];
    int t, total = 0;

    bzero(buffer, sizeof buffer);
    printf("I have a new client\n");

    sleep(60);

    while((t = read(sockfd, buffer, sizeof buffer)) > 0)
    {
        total += t;
        printf("%d ", total);
    }
    printf("nb chars read: %d\n", total);

    if(t < 0)
    {
        perror("read");
    }

    printf("I don't have that client anymore\n");
    return 0;
}
4

2 に答える 2

0

あなたは正しい軌道に乗っていますが、ソケット送信バッファは 48k 以上になる可能性があります。それは多くの反復です。1 バイトだけでなく、一度に 8k を書き込んでみてください。そして、受信機が読み取るまでの時間を増やします。

注意これをテストする必要はありません。ブロッキング モードではブロックし、非ブロッキング モードでは EAGAIN/EWOULDBLOCK で失敗します。マニュアルページを参照してください。

于 2014-03-31T12:10:17.140 に答える