0

私はネットワークプログラミングに不慣れで、SocketAPIを利用する小さなプログラムを書くことでこれを学んでいます。現在、私は単純なエコーサーバーを作成しています。これは、フォークを使用してそのコピーを作成します。接続要求を受け取るとすぐに、以前の反復 サーバー(ここ)よりも改善されます。ただし、サーバーを起動してクライアントを起動し、コンソールにメッセージを入力すると、予期せず終了します。Gdbでプログラムを実行すると、それSIGPIPEが配信されたことがわかります。しかし、ソケットがまだ有効である限り、SIGPIPEは発生していないはずです。関係するあらゆる種類の助けをいただければ幸いです。これがクライアントコードです

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>

#define MAXCOUNT 1024

int main(int argc, char* argv[])
{
    int sfd,i;
    struct sockaddr_in saddr;
    char buff[MAXCOUNT];
    char mesg[MAXCOUNT];
    sfd = socket(AF_INET,SOCK_STREAM,0);
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    inet_pton(AF_INET,"127.0.0.1",&saddr.sin_addr);
    saddr.sin_port = htons(5008);
    connect(sfd,(struct sockaddr*) &saddr,sizeof(saddr));
    fgets(buff,MAXCOUNT,stdin);
    send(sfd,buff,strlen(buff),0);
    if (recv(sfd,mesg,MAXCOUNT,0) == -1) {
        perror("Nothing to read\n");
        exit(1);
    }
    printf("%s\n",mesg);
    exit(0);    
}

これがサーバーコードです

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <string.h>

#define MAXCOUNT 1024

int main(int argc, char* argv[])
{
    int sfd,nsfd,cn;
    pid_t c;
    char buf[MAXCOUNT];
    socklen_t clen;
    struct sockaddr_in caddr,saddr;

    sfd = socket(AF_INET,SOCK_STREAM,0);
    memset(&saddr,0,sizeof(saddr));
    saddr.sin_family = AF_INET;
    saddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
    saddr.sin_port = htons(5008);

    bind(sfd,(struct sockaddr*) &saddr,0);

    listen(sfd,2);
    for (; ;) {
        clen = sizeof(caddr);
        nsfd = accept(sfd,(struct sockaddr*) &caddr, &clen);
        if( (c = fork()) == 0) {
            close(sfd);
            memset(buf,0,sizeof(buf));
            cn = recv(nsfd,buf,sizeof(buf),0);
            if ( cn == 0) {
                perror("Reading from the client socket failed\n PROGRAM CRASH :\n");
                exit(1);
            }
            buf[cn] = '\0';
            send(nsfd,buf,strlen(buf),0);
            close(nsfd);
            exit(0);
        }
    }
    return 0;
}
4

1 に答える 1

0
send(sfd,buff,strlen(buff),0);
if (recv(sfd,mesg,MAXCOUNT,0) == -1) {
    perror("Nothing to read\n");
    exit(1);
}
printf("%s\n",mesg);

書式指定子は、%s任意のデータではなく、C スタイルの文字列用です。また、 からの戻り値を破棄するため、recv取得したバイト数を知る方法がありません。

また、クライアントはソケットを正常にシャットダウンしたり、サーバーが送信する可能性のあるすべてのデータを受信したことを確認したりしません。そのため、異常終了を引き起こしている可能性があります。サーバーは送信が完了すると接続を閉じるため、クライアントは接続が閉じられたことを検出するまで受信を試行し続ける必要があります。

于 2012-02-04T10:00:34.907 に答える