c TCPサーバ及びクライアント

13652 ワード

一、TCP/IPネットワークプログラミングの予備知識
1、socket 1、特殊なファイル記述子:ファイルの形式で操作することができ、異なるプロセス間のインタラクションを実現することができる2、1つの関数(関数は特殊なファイルを作成するために使用される)3、接続向けまたは無接続2、IPアドレスは対端のアドレス3を得ることができ、ポート番号はサーバーまたはカスタマーサービス側が実行するプロセス4、バイト順の2種類の記憶方式である:大端記憶、小端記憶小端記憶:データの低位記憶は低アドレス方向大端記憶、データの高位記憶は低アドレス方向二、socketタイプ1、フローソケット(TCP/IP)2、データレポートソケット(UDP)3、元ソケット三、ネットワークプログラミング常用関数1、socket()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int socket(int domain,int type,int protocol);パラメータ1:domain:アドレスファミリーAF_UNIX, AF_LOCAL     Local communication       unix(7)            AF_INET          IPv4 Internet protocols     ip(7)            AF_INET 6 IPv 6パラメータ2:type:ソケットタイプSOCK_STREAM             SOCK_DGRAM            SOCK_SEQACK ETパラメータ3:protocol:通常02、bind()ヘッダファイル:#include/*See NOTES*/#include関数プロトタイプ:int bind(int sockfd、const struct sockaddr*addr、socklen_t addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さ3,listen()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int listen(int sockfd,int backlog);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,backlog:定義キューの最大長4,accept()ヘッダファイル:#include/*See NOTES*/#include
関数プロトタイプ:int accept(int sockfd,struct sockaddr*addr,socklen_t*addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,addr:構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さのアドレス戻り値:新しいsocketファイル記述子5,connect()ヘッダファイル:#include/*See NOTES*/#include関数プロトタイプ:int connect(int sockfd,const struct sockaddr*addr,socklen_t addrlen);パラメータ1,sockfd:socket関数呼び出し返されるファイル記述子パラメータ2,構造体のアドレスパラメータ3,addrlen:sockaddrアドレス構造の長さ6,send()/recv()/write()この2つの関数は受信と送信を表す.TCP/IPサーバ1、リスニングソケットの作成socket()関数2、バインドipおよびポートbind()関数3、リスニングの開始listen()関数4、accept()関数の開始5、データの送受信read()/write()の2つの関数は、受信および送信を表す.TCP/IPクライアント1、ソケットソケットの作成()2、接続サーバconnect()3、送受信データread()/write()の2つの関数は、受信と送信を表します.
 
サーバとクライアントの3回の握手:
最初の握手:クライアントは接続の確立要求を開始し、SYNとシーケンス番号iを送信する.
2回目の握手:サーバはクライアントとの接続を確認し、SYNと独自のシリアル番号jを送信し、ACKと確認値i+1を同時に送信する
3回目の握手:クライアントはサーバにACKおよび確認値j+1を送信する
 
サーバとクライアントの手を4回振る:
最初の手を振る:アクティブに切断する側は接続を閉じることを要求して、そしてFINを送信します
2回目の手を振る:パッシブブレーク側確認クローズ接続送信ACKと確認値i+2
3回目の手を振る:受動的に切断した方がFINを送信します
4回目の手を振る:自発的に切る方がACKと確認値J+2を送って確認を表す
 
サーバ
#include 
#include 
#include <string.h>
#include 
#include 
#include 
#include in.h>
#include 
#include 

int main()
{
     int listenfd,connfd;
     int listenfd = socket(AF_INET,SOCK_STREAM,0);
     if(listenfd == -1)
     {
          perror("socket");
          return -1;  
     }
     
     int on = 1;
     int ret = setsockopt(listenfd,SOL_SOCKET,SO_REUSEADDR,&on,sizeof(on));
     if(-1 == ret){
         perror("setsockopt");
         return -1;
     }

     struct sockaddr_in saddr,caddr;
     saddr.sin_family = AF_INET;
     saddr.sin_port = htons(8888);
     //   
     saddr.sin_addr.s_addr = htonl(INADDR_ANY);
     // 
     //saddr.sin_addr.s_addr = inet_addr("127.0.0.1");
     
     ret = bind(listenfd,(struct sockaddr *)(&saddr),sizeof(saddr));
     if(-1 == ret){
          perror("bind");
          return -1;
    }  
     ret = listen(listenfd, 5);
     if(-1 == ret){
          perror("listen");
          return -1;
     }

     char buf[1024];
     addrlen = sizeof(caddr);
     while(1)
     {
             connfd = accept(listenfd, (struct sockaddr *)&caddr, &addrlen);
             if(-1 == ret){
                    perror("accept");
                    return -1;
             }
             inet_ntop(AF_INET,&caddr.sin_addr,cip,INET_ADDRSTRLEN);
             printf("client ip = %s, port = %d
",cip,ntohs(caddr.sin_port));  // ip memset(buf,0,sizeof(buf)); ret = read(connfd, buf, sizeof(buf)); if(-1 == ret){ perror("read"); return -1; } ret = write(connfd,buf,sizeof(buf)); if(-1 == ret){ perror("write"); return -1; } } }

クライアント
#include 
#include 
#include <string.h>
#include 
#include 
#include 
#include in.h>
#include 
#include 

int main()
{
     char buf[1024];
     int sockfd;
     struct sockaddr_in saddr;
     
     sockfd = socket(AF_INET, SOCK_STREAM, 0);
     if(-1 == sockfd){
            perror("socket");
            return -1;
     }
     
     saddr.sin_family = AF_INET;
     saddr.sin_port = htons(8888);
     saddr.sin_addr.s_addr = htonl(INADDR_ANY);

     int ret = connect(sockfd, (struct sockaddr *)&saddr, sizeof(saddr));
     if(-1 == ret){
            perror("connect");
            return -1;
     }

      while(1)
      {
             memset(buf, 0 , sizeof(buf));
             scanf("%s", buf);
             ret = write(sockfd, buf, sizeof(buf));
             if(-1 == ret)
             {
                     perror("write");
                     return -1;
             }
             ret = read(sockfd, buf, sizeof(buf));
             if(-1== ret){
                     perror("read");
                     return -1;
             }
             printf("buf = %s
",buf); } }