0

クライアントにメッセージを送信する必要があり、クライアントはオプションで応答する必要があります。クライアントとサーバーが接続するまで取得しますが、両方のプログラムが「セグメンテーション違反」で終了します。このエラーの意味を知っている人はいますか? クライアントとサーバーが対話するコードを作成する方法について、誰かがアイデアを提供できますか。クライアントが選択したオプションを受け取った後、サーバーはそれを分析し、結果をクライアントに再度送信する必要があります。

私のコードは次のとおりです。

サーバ

    int
main(int argc, char **argv)
{
    int                 listenfd, connfd;
    socklen_t           len;
    struct sockaddr_in  servaddr, cliaddr;
    char                buff[MAXLINE];
    time_t              ticks;
    char                message[MAXLINE]="This is the server";
    char                temp_scale[2];
    char                recvdata[MAXLINE + 1];

    listenfd = Socket(AF_INET, SOCK_STREAM, 0);
    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);/*----------------------------------------------------*/
    servaddr.sin_port        = htons(5555); 

    Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));
    Listen(listenfd, LISTENQ);

    for ( ; ; )
    {
        len = sizeof(cliaddr);
        connfd = Accept(listenfd, (SA *) &cliaddr, &len);

        printf("Connection from %s, port %d\n",
               Inet_ntop(AF_INET, &cliaddr.sin_addr, buff, sizeof(buff)),
               ntohs(cliaddr.sin_port));


        snprintf(message, sizeof(message), "%s\r\n");
            Writen(connfd, message, strlen(message));
            while ( (n = read(connfd, recvdata, MAXLINE)) > 0)
            {
             recvdata[n] = 0;   /* null terminate*/
             if (fputs(recvdata, stdout) == EOF)
                 err_sys("fputs error");
            }
             if (n < 0)
          err_sys("read error");

           Close(connfd);
    }
}

クライアント

int
main(int argc, char **argv)
{
    int                 sockfd, rd;
    socklen_t           len;
    char                recvline[MAXLINE + 1];
    struct sockaddr_in  servaddr, cliaddr;
    char  scale[2];

    /*if (argc != 2)
        err_quit("usage: a.out <IPaddress>");*/

    if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
        err_sys("socket error");

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port   = htons(atoi(argv[2])); /*port passed through command line*/
    if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) /*The client translates the server address, passed on the command line*/
        err_quit("inet_pton error for %s", argv[1]);


    if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
        err_sys("connect error");

    len = sizeof(cliaddr);
    Getsockname(sockfd, (SA *) &cliaddr, &len);
    printf("Local Address is: %s\n",
           Sock_ntop((SA *) &cliaddr, sizeof(cliaddr))); 

    printf("Iniciando read...\n");
    while ( (rd = read(sockfd, recvline, MAXLINE)) > 0)
    {
        recvline[rd] = 0;   /* null terminate*/
        if (fputs(recvline, stdout) == EOF)
            err_sys("fputs error");
    }
    if (rd < 0)
     err_sys("read error");

    printf("Enter option 'A' or 'B'");
    send_scale(sockfd);

    exit(0);
}

ありがとう

4

3 に答える 3

2

コードをデバッガー (例: gdb ./a.out) で実行すると、すぐにわかります。

于 2013-03-22T07:54:53.617 に答える
2

次の理由により、サーバーに障害が発生している可能性があります。

snprintf(message, sizeof(message), "%s\r\n"); // <== no parameters

それは完全に間違っています。呼び出しには、null で終わる文字列をsnprintf()期待する書式指定子があり、char *まったく何も渡していません。したがって、スタックからランダムな値を取得し、それをポインターとして扱い、フォーマットされた要求を満たすために逆参照します。

使用している API の詳細を知らなければ (名前だけでは明らかに標準の BSD ソケットではありません)、これ以上先に進むことはできません。

于 2013-03-22T08:10:51.737 に答える
1

それが役立つかどうかはわかりませんが、C では、応答を出力すると、文字列の null 終端は '\0' になります。

recvdata[n] = 0;   /* null terminate ----> this must be '\0'*/
if (fputs(recvdata, stdout) == EOF)
err_sys("fputs error");

「0」でパディングすると、fputsが文字列を解析して出力するときにセグメンテーション違反が発生する可能性があります。

それが役に立てば幸い!

于 2013-07-08T15:11:52.737 に答える