2016-10-21 1 views
0

私は単純なクライアント/サーバプログラムを作ろうとしていますが、クライアント上では必ずSegmentationフォールトを取得します。私はIPアドレス、ポート、多くの代替ソリューションを試してみましたが、私にとってはうまくいきませんでした。ソケットクライアントがKaliで動作しない

サーバコード:

#include <arpa/inet.h> 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <string.h> 
    #include <sys/types.h> 
    #include <sys/socket.h> 
    #include <netinet/in.h> 
    #include <netdb.h> 
    int main(int argc, char const *argv[]) 
    { 
     int sock,mysock; 
     struct sockaddr_in server; 
     char buff[1024]; 

    char s[256]; 

    if (!gethostname(s, sizeof s)) 
     { 
      printf ("Machine: %s\n", s); 
      { 
       struct hostent *host= gethostbyname(s); 

       if (host != NULL) 
       { 
        struct in_addr **adr; 

        for (adr = (struct in_addr **)host->h_addr_list; *adr; adr++) 
        { 
         printf("IP : %s\n", inet_ntoa(**adr)); 
        } 
       } 
      } 
     } 


     /*creation du socket*/ 
     sock=socket(AF_INET,SOCK_STREAM,0); 
     if (sock<0) 
     { 
      perror("creation de socket echouer\n"); 
      exit(1); 
     } 
     server.sin_family=AF_INET; 
     server.sin_addr.s_addr=INADDR_ANY; 
     server.sin_port=5000; 

     if (bind(sock, (struct sockaddr *) &server,sizeof(server)) < 0) 
      {perror("ERROR on binding"); 
       exit(1);} 

     /*listen for just 1 connection*/ 
     listen(sock,1); 
     mysock=accept(sock,(struct sockaddr *)0,0); 
     if (mysock==-1) 
     { 
      perror("accept failed"); 
      exit(1); 
     } 




     write(mysock,"you are connected to: my server\n",55); 
     read(mysock,buff,sizeof(buff)); 
     printf("%s\n",buff); 
     gets(); 
     close(sock); 
     close(mysock); 


     return 0; 
    } 

クライアントコード:

#include <arpa/inet.h> 
#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <netinet/in.h> 
#include <netdb.h> 
int main(int argc, char const *argv[]) 
{ 
    int sock; 
    struct sockaddr_in server; 
    struct hostent *hp; 
    char buff[1024]; 

    /*creation du socket*/ 
    sock=socket(AF_INET,SOCK_STREAM,0); 
    if (sock<0) 
    { 
     perror("creation de socket echouer\n"); 
     exit(1); 
    } 
    server.sin_family=AF_INET; 
    hp = gethostbyname(argv[1]); 
    if (hp == NULL) { 
     perror("ERROR, no such host\n"); 
     exit(0); 
    } 
    printf("0\n"); 
    server.sin_addr.s_addr=inet_addr("127.0.1.1"); 
    server.sin_port=htons(5000); 
printf("1\n"); 
    if (connect(sock,(struct sockaddr *)&server,sizeof(server)<0)) 
    { 
     perror("connection failed"); 
     exit(1); 
    }printf("2\n"); 
    read(sock,buff,sizeof(buff)); 
    printf("%s\n",buff); 
    write(sock,"thanks for accepting me\n",25); 

    system("PAUSE"); 
    close(sock); 
    return 0; 
} 
+1

のような引数

  • セットのポート番号は、あなたのプログラムに引数を渡す必要があるため。 – Anshuman

  • +0

    引数を指定してプログラムを実行します。エラー表示を開始します – Anshuman

    +1

    SOはデバッグサービスではありません。シンボルでコンパイルするには、デバッガ内でコードを実行し、プログラムを1行ずつトレースして、関連する変数の値を調べ、実際に何が起こっているのかを調べます。 *具体的な質問が発生した場合は、ここに戻って自由に感じてください。 – alk

    答えて

    1

    は多くの問題があるかもしれませんが、この1は間違いなく間違っている:

    your code: if (connect(sock,(struct sockaddr *)&server,sizeof(server)<0)) 
    correct:  if (connect(sock,(struct sockaddr *)&server,sizeof(server))<0) 
                         ^^^^ 
    
    +0

    こんにちは、ありがとう私は問題を投稿した後に接続できないことに気づいた –

    2

    あなたがこの行の結果にクライアント上でセグメンテーションフォールトを得たようだ:

    hp = gethostbyname(argv[1]); 
    

    セグメンテーション違反ここで取得する方法はNULL -pointerを渡すことです。したがって、コマンドライン引数なしでクライアントを実行するたびにこれを実行します。
    P.あなたはそれがなぜ必要なのか、全く理解していない。


    注:

    • 例えばとして明らかに失策を修正するとよいでしょうSteffenは言いました。また、問題を避けるために、次のようなバッファを初期化してください:char buff[1024] = {0};。また、関数の戻り値を調べて、エラーが発生しているかどうかを確認します。 manから

    のgethostbyname *()とのgethostbyaddr *()関数は、廃止されました。 アプリケーションでは、getaddrinfo(3)とgetnameinfo(3)を代わりに使用する必要があります。


    EDIT: だからあなたのクライアントのための作業コードは、このようなことができます:

    int main(int argc, char const *argv[]) { 
        int sock; 
        ssize_t bytes; 
        struct sockaddr_in server; 
        char buff[1024] = {0}, tosend[] = "thanks for accepting me"; 
        /* 
        struct hostent *hp; 
        if(argv[1]) { 
         hp = gethostbyname(argv[1]); 
         if (hp == NULL) { 
          perror("gethostbyname"); 
          return; 
         } 
         // something with hp 
        } 
        */ 
        /*creation du socket*/ 
        sock = socket(AF_INET, SOCK_STREAM, 0); 
        if (sock < 0) { 
         perror("socket"); 
         exit(1); 
        } 
        memset(&server, 0, sizeof (struct sockaddr_in)); 
        server.sin_family = AF_INET; 
        server.sin_addr.s_addr = inet_addr("127.0.1.1"); 
        server.sin_port = htons(5000); 
        printf("1\n"); 
        if (connect(sock, (struct sockaddr *)&server, sizeof server) < 0) { 
         perror("connect"); 
         exit(1); 
        } 
        printf("2\n"); 
        if ((bytes = read(sock, buff, sizeof(buff) - 1)) < 0) { 
         perror("read"); 
         exit(1); 
        } else if (! bytes) 
         puts("finished"); 
         else 
         printf("%s\n", buff); 
        if (write(sock, tosend, sizeof tosend) < 0) 
         perror("write"); 
    
        return 0; 
    } 
    

    あなたはコメント行を使用する場合は、./client somename

    のようなクライアントを実行するときに、いくつかのコマンドライン引数を渡します

    サーバー側のあなたは少なくとも次のものを変更する必要がありますS:

    • 削除するかgets()コールを変更する、それがhtons(5000)
    +0

    segfaultを取得する別の方法は、 'argv'配列の存在しない要素にアクセスすることです。ネットワークバッファを初期化する必要はありません。 – EJP

    +0

    @EJP恐らく、確かではありません。私はそのような方法でセグメンテーションを誘発することはできません。 バッファの場合。初期化されていないバッファがスタック上の前の関数によって残されたゴミを指している場合があります。したがって、例えば、 "AAAAAA \ 0"に変更し、サーバーから "BBB"のような3バイトを読み取ると、 "BBBAAA \ 0"のような文字列を文字列として取得できます。だから、私はバッファを初期化するのがいいと言いました。 – red0ct

    +0

    誰かが私のコードを修正して投稿できますか? –

    関連する問題