TCP协议是应用在传输层的协议。是一种面向连接的、可靠的协议。

TCP协议的特点:

1)面向字节流。

2)TCP是面向连接的运输层协议

3) 每一条TCP链接只能有两个端点

4)TCP提供可靠交付的服务

5)TCP提供全双工通信

根据TCP协议三次握手,server一直处于监听状态,等接受到client的请求连接(connect)信号,accept该连接。


  server:
   1 #include<stdio.h>
  2 #include<string.h>
  3 #include<unistd.h>
  4 #include<stdlib.h>
  5 #include<sys/socket.h>
  6 #include<sys/types.h>
  7 #include<netinet/in.h>
  8 #include<arpa/inet.h>
  9 #define _BACKLOG 5
 10 void usage(char *_proc)
 11 {
 12     printf("usage: %s,[ip],[proc]",_proc);
 13 }
 14 int startup(const char *ip,const int port)
 15 {
 16     int sock = socket(AF_INET,SOCK_STREAM,0); //创建套接字
 17     if(sock < 0)
 18     {
 19         perror("socket");
 20         exit(1);
 21     }
 22     struct sockaddr_in local;
 23     local.sin_family = AF_INET;
 24     local.sin_port = htons(port);
 25     local.sin_addr.s_addr = inet_addr(ip);
 26     if(bind(sock,(struct sockaddr*)&local,sizeof(local))<0) //将IP和端口号绑定
 27     {
 28         perror("bind");
 29         exit(2);
 30     }
 31     if(listen(sock,_BACKLOG)<0) //监听是否有进程与之创建连接
 32     {
 33         perror("listen");
 34         exit(3);
 35     }
 36     return sock;
 37 }
 38 void* pthread(void * arg)
 39 {
 40     int sock = (int)arg;
 41     char buf[1024];
 42     while(1)
 43     {
 44         ssize_t size = read(sock,buf,sizeof(buf)-1);
 45         if(size>0)
 46         {
 47             buf[size] = '\0';
 48         }
 49         else if(size==0)
 50         {
 51             printf("client close...\n");
 52             break;
 53         }
 54         else
 55         {
 56             perror("read");
 57             exit(3);
 58         }
 59         printf("client say: %s\n",buf);
 60     }
 61     close(sock);
 62     return NULL;
 63 }
 64 
 65 int main(int argc,char *argv[])
 66 {
 67     if(argc != 3)
 68     {
  69         usage(argv[0]);
 70         exit(1);
 71     }
 72     char *ip = argv[1];
 73     int port = atoi(argv[2]);
 74     int listen_sock = startup(ip,port);
 75     struct sockaddr_in client;
 76     socklen_t len = sizeof(client);
 77     while(1)
 78     {
 79         int new_sock = accept(listen_sock,(struct sockaddr*)&client,&len);
 80         if(new_sock<0)
 81         {
 82             perror("accept");
 83             continue;
 84         }
 85         printf("get a client... sock %d,ip: %s,port: %d\n",new_sock,inet_nto    a(client.sin_addr),ntohs(client.sin_port));
 86 #ifdef _V1_ //单进程通信
 87         char buf[1024];
 88         while(1)
 89         {
 90             ssize_t size = read(new_sock,buf,sizeof(buf)-1);
 91             if(size>0)
 92             {
 93                 buf[size] = '\0';
 94             }
 95             else if(size==0)
 96             {
 97                 printf("client close...\n");
 98                 break;
 99             }
100             else
101             {
102                 perror("read");
103                 exit(3);
104             }
105             printf("client say :%s\n",buf);
106         }
107 #elif _V2_ //多进程
108         pid_t pid = fork();
109         if(pid<0)
110         {                              
111             perror("fork");
112             exit(4);
113         }
114         else if(pid == 0)
115         {//child
116             close(listen_sock);
117             char *_client = inet_ntoa(client.sin_addr);
118             char buf[1024];
119             while(1)
120             {
121                 memset(buf,'\0',sizeof(buf));
122                 ssize_t size = read(new_sock,buf,sizeof(buf)-1);
123                 if(size>0)
124                 {
125                     buf[size] = '\0';
126                 }
127                 else if(size==0)
128                 {
129                     printf("[ip]:%s close...\n",_client);
130                     break;
131                 }
132                 else
133                 {
134                     perror("read");
135                     exit(3);
136                 }
137                 printf("[ip]:%s say :%s\n",_client,buf);
138             }
139             close(new_sock);
140             exit(0);
141         }
142         else
143         {//father
144             close(new_sock);
145         }
146 #elif _V3_ //多线程
147         pthread_t pid;
148         pthread_create(&pid,NULL,pthread,(void*)new_sock);
149         pthread_detach(pid);
150 #else
151         printf("default");
152 #endif
153     }
154     return 0;
155 }

client:
   1 #include<stdio.h>
  2 #include<unistd.h>
  3 #include<stdlib.h>
  4 #include<sys/socket.h>
  5 #include<sys/types.h>
  6 #include<netinet/in.h>
  7 #include<arpa/inet.h>
  8 
  9 void usage(char *proc)
 10 {
 11     printf("usage:%s,[remote ip],[remote proc]",proc);
 12 }
 13 int main(int argc,char *argv[])
 14 {
 15     if(argc != 3)
 16     {
 17         usage(argv[0]);
 18         exit(1);
 19     }
 20     int sock = socket(AF_INET,SOCK_STREAM,0);
 21     if(sock<0)
 22     {
 23         perror("sock");
 24         exit(1);
 25     }
 26     int port = atoi(argv[2]);
 27     char *ip = argv[1];
 28     struct sockaddr_in remote;
 29     remote.sin_family = AF_INET;
 30     remote.sin_port = htons(port);
 31     remote.sin_addr.s_addr = inet_addr(ip);
 32 
 33     int ret = connect(sock,(struct sockaddr*)&remote,sizeof(remote));
 34     if(ret<0)
 35     {
 36         perror("connect");
 37         exit(2);
 38     }
 39     char buf[1024];
 40     while(1)
 41     {
 42         printf("please say: ");
 43         scanf("%s",buf);
 44         ssize_t size = write(sock,buf,sizeof(buf)-1);
 45 
 46     }
 47     return 0;
 48 }
 
 结果:
[fbl@localhost tcp]$ ./tcp_server 192.168.1.106 8080
get a client... sock 4,ip: 192.168.1.106,port: 51708
client say: hello
client say: hi
client say: nihao
client close...
^C
[fbl@localhost tcp]$ 
[fbl@localhost tcp]$ ./tcp_client 192.168.1.106 8080
please say: hello
please say: hi
please say: nihao 
please say: ^C
[fbl@localhost tcp]$