linux下のC/Sプログラム

3135 ワード

Linuxプログラム設計におけるsocketソケットに関する章ソケットの通信フローの紹介を見た後,クライアント側とサーバ側のプログラムを自分で書いた.注意すべき問題がいくつか見つかった.
クライアント:
  • ソケットインターネットアドレスs_addrは直接127.0を用いることができない.0.1またはこの文字列「127.0.0.1」で値を割り当てるのではなく、inet_を使用します.addr("127.0.0.1").
  • connect関数でaddress_lenは直接数字を書くべきではありません.例えば4ではなくsizeof(address)を使うべきです.ここのaddressはソケットアドレスです.struct sockaddr_inタイプ.
  • connect関数のaddressはsockaddr_を直接使用できませんInタイプ変数のアドレスではなく、このアドレスに(struct sockaddr*)強制タイプ変換
  • を追加する必要があります.
  • write関数の3つのパラメータは、直接文字列ではありません.3つのパラメータはそれぞれクライアントソケットで、2つ目は送信するデータのキャッシュアドレスで、後ろのデータ長は、直接数字を使います.
  • close()には、ソケットのパラメータがあるはずです.
  • socket関数の3番目のパラメータは、デフォルトで0と書く必要があります.
  • socket関数はintタイプの記述子を返します.ソケットが正常に作成されたかどうかを判断するのに使用しないほうがいいです.
  • #include<sys/socket.h>
    #include<netinet/in.h>
    #include<stdio.h>  //           
    #include<sys/types.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    int main()
    {
        //char *buff;
     int serversoc=socket(AF_INET,SOCK_STREAM,0),clientsoc;
     struct sockaddr_in address,clientaddress;
     address.sin_family=AF_INET;
     address.sin_port=9734;
     address.sin_addr.s_addr=inet_addr("127.0.0.1");
     if(bind(serversoc,(struct sockaddr*)&address,sizeof(address))==-1)
     {
         printf("bind fail!");
      return -1;
     }
     if(listen(serversoc,8)==-1)
     {
         printf("listen fail!");
      return -1;
     }
     size_t client_addr_len=sizeof(address);
     int len=sizeof(clientaddress);
     while(1)
     {
     char ch;
     clientsoc=accept(serversoc,(struct sockaddr*)&clientaddress,(socklen_t *__restrict)&len);
     read(clientsoc,&ch,1);
            printf("data from client:%c
    ",ch);  //ch++;         //write(clientsoc,&ch,1);  close(clientsoc);  }     return 0; }

    サーバ側:
  • read()関数の最初のパラメータは、サーバ側の記述子ではなくクライアントの記述子です.
  • accept()関数の3番目のパラメータはクライアントのアドレス長のポインタであるべきで、&sizeof(address)を実パラメータにすることができず、sizeofがオブジェクトを返すなど、int len=sizeof(address)を使うべきである.そして実参&len.そして&lenの前に(socklen_t*_restrict)を付けて強制変換します.
  • accept()関数の2番目のパラメータは、サーバのaddressポインタではなく、クライアントのaddressポインタです.タイプ変換を行います.
  • close()の記述子は、サーバ記述子ではなくacceptによって返されるクライアント記述子である.
  • accept()とread()はwhileに置くべきです.ループ受信および読み出し
  • #include<sys/socket.h>
    #include<netinet/in.h>
    #include<stdio.h>   //           
    #include<sys/types.h>
    #include<arpa/inet.h>
    #include<unistd.h>
    int main()
    {
       char ch='a';
       int clientsoc=socket(AF_INET,SOCK_STREAM,0);
       struct sockaddr_in address;
       address.sin_family=AF_INET;
       address.sin_port=9734;
       address.sin_addr.s_addr=inet_addr("127.0.0.1");
       int connec=connect(clientsoc,(struct sockaddr*)&address,sizeof(address));
       if(connec==-1){printf("connection fail");return -1;}
       write(clientsoc,&ch,1);
       //read(clientsoc,&ch,1);
       //printf("data from server:%c
    ",ch);    close(clientsoc);    return 0; }

    同じマシンでなければ、IPなども修正します.
    注意:サーバ側の出力では省略できません.そうしないとデータが見えません.
    もう一つ興味深いことに、charタイプをchar*に変更すると、対応する出力が変更され、有無に差があり、このときスペースに変更してもデータがサーバに表示されません.どうしてですか.深く考える価値がある!