Socket 下TCP通信学习笔记


由于公司需要开发底层套接字通信,所以把大一的C重新拾回来学习,但是就学校的那点皮毛远远达不到公司项目的要求,一切重来,学习Linux下的C编程。 以Linux下TCP socket通信为实例。 在Socket通信中,服务器端分为socket初始化、绑定、监听、接受连接、发送接收数据五个过程,客户端分为socket初始化、连接服务器socket、发送接收数据三个过程。如图所示。 作为初学者,socket套接字学习的关键点在于那几个函数的学习和理解。 代码先上,解析在注释中: 说明:本代码已经加入多线程问题,请查阅时注意。Linux下GCC编译通过。 server.c:
  1 /* 
  2  * server.c 
  3  * 
  4  *  Created on: 2011-3-13 
  5  *      Author: n2 
  6  */  
  7   
  8 #include <pthread.h>  
  9 #include <stdio.h>  
 10 #include <stdlib.h>  
 11 #include <string.h>  
 12 #include <unistd.h>  
 13 #include <sys/types.h>   
 14 #include <sys/socket.h>  
 15 #include <netinet/in.h>  
 16   
 17 #define PORTL 8742  
 18   
 19 pthread_t th1,th2;  
 20 //声明读写函数  
 21 void *recv_info(int newsockfd);  
 22 void *send_info(int newsockfd);  
 23 //输出错误提示  
 24 void error(const char *msg)  
 25 {  
 26     perror(msg);  
 27     exit(1);  
 28 }  
 29   
 30 int main(int argc, char *argv[])  
 31 {  
 32      int sockfd, newsockfd;  
 33      unsigned int clilen;  
 34      struct sockaddr_in serv_addr, cli_addr;//socket通信中Internet地址变量定义  
 35   
 36      sockfd = socket(AF_INET, SOCK_STREAM, 0);//初始化socket  
 37      if (sockfd < 0)  
 38         error("ERROR opening socket");  
 39      bzero((char *) &serv_addr, sizeof(serv_addr));//地址变量进行清零  
 40   
 41      serv_addr.sin_family = AF_INET;  
 42      serv_addr.sin_addr.s_addr = INADDR_ANY;  
 43      serv_addr.sin_port = htons(PORTL);//地址变量添加协议簇、监听地址、端口  
 44      if (bind(sockfd, (struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)//绑定socket  
 45               error("ERROR on binding");  
 46      listen(sockfd,10);  
 47   
 48      clilen = sizeof(cli_addr);  
 49        
 50      while(1){  
 51          newsockfd = accept(sockfd,(struct sockaddr *) &cli_addr,&clilen);//阻塞等待连接  
 52   
 53          //连接成功,创建读写线程  
 54          memset(&th1, 0, sizeof(th1));  
 55          memset(&th2, 0, sizeof(th2));  
 56          int thr1 = pthread_create(&th1,NULL,recv_info,newsockfd);  
 57          if(thr1!=0)  
 58              printf("recv Creation failed!/n");  
 59          int thr2 = pthread_create(&th2,NULL,send_info,newsockfd);  
 60          if(thr2!=0)  
 61              printf("send Creation failed!/n");  
 62      }  
 63      //等待线程结束  
 64     pthread_join(th1,NULL);  
 65     pthread_join(th2,NULL);  
 66   
 67     close(sockfd);  
 68     return 0;  
 69 }  
 70   
 71 //读取来自于客户端的数据并显示  
 72 void *recv_info(int newsockfd)  
 73 {  
 74         int n;  
 75         char buffer[512];  
 76   
 77         if (newsockfd < 0)  
 78             pthread_exit((void *)1);  
 79         else  
 80         {  
 81             while(1)  
 82             {  
 83                 bzero(buffer,512);  
 84                 n = recv(newsockfd,buffer,sizeof(buffer),0);  
 85                 printf("From client: %s/n",buffer);  
 86                 if (n < 0)  
 87                     pthread_exit(NULL);  
 88                 else  
 89                     //当读取数据为'0'时关闭读取线程  
 90                     if(buffer[0]=='0')  
 91                         pthread_exit(NULL);  
 92             }  
 93         }  
 94 }  
 95 //向客户端发送数据  
 96 void *send_info(int newsockfd)  
 97 {  
 98         int n;  
 99         char buffer[256];  
100         bzero(buffer,256);  
101         while(1)  
102         {  
103             if(newsockfd<0)  
104                 error("ERROR on accept");  
105             gets(buffer);  
106             n =send(newsockfd,buffer,sizeof(buffer),0);  
107             if (n < 0)  
108                 error("ERROR writing to socket");  
109             if(buffer[0]=='0')  
110                 //当发送数据为'0'时关闭发送线程  
111                 pthread_exit((NULL);  
112         }  
113 }  
client.c
 1 /* 
 2  * client.c 
 3  * 
 4  *  Created on: 2011-3-13 
 5  *      Author: n2 
 6  */  
 7  
 8 #include   <pthread.h>  
 9 #include   <stdlib.h>  
10 #include   <stdio.h>  
11 #include   <errno.h>  
12 #include   <string.h>  
13 #include   <netdb.h>  
14 #include   <sys/types.h>  
15 #include   <netinet/in.h>  
16 #include   <sys/socket.h>  
17 #include   <unistd.h>  
18  
19 #define PORTL 8742  
20 pthread_t th1,th2;  
21   
22 void *send_info(int saiCId);  
23 void *read_info(int saiCId);  
24   
25 int main()  
26 {  
27     struct sockaddr_in saiClient;  
28     int saiCId , connectId ;  
29   
30     char * host_name="192.168.1.233";//服务器端IP地址  
31     struct hostent *server_host_name;  
32     server_host_name = gethostbyname(host_name);  
33   
34   
35     saiClient.sin_family = AF_INET;  
36     saiClient.sin_port = htons(PORTL);  
37     saiClient.sin_addr.s_addr= ((struct in_addr *)(server_host_name->h_addr))->s_addr;//转义字符串格式的IP地址  
38   
39     saiCId = socket(AF_INET,SOCK_STREAM,0);  
40   
41      memset(&th1, 0, sizeof(th1));  
42      memset(&th2, 0, sizeof(th2));  
43   
44   
45      connectId = connect(saiCId,(struct sockaddr *)(&saiClient),sizeof(struct sockaddr_in));  
46      if(connectId<0)  
47          printf("connect failed!");  
48   
49      int thr1 = pthread_create(&th1,NULL,send_info,saiCId);  
50      if(thr1!=0)  
51          printf(" Send Thread Creation failed!/n");  
52   
53      int thr2 = pthread_create(&th2,NULL,read_info,saiCId);  
54      if(thr2!=0)  
55          printf(" Send Thread Creation failed!/n");  
56   
57     pthread_join(th1,NULL);  
58     pthread_join(th2,NULL);  
59   
60     close(saiCId);  
61 }  
62   
63 void *send_info(int saiCId)  
64 {  
65     int n;  
66     char buffer[256];  
67     while (1)  
68     {  
69         bzero(buffer, 256);  
70         gets(buffer);  
71   
72         n = send(saiCId, buffer, sizeof(buffer), 0);  
73         if (n < 0)  
74             error("ERROR writing to socket");  
75         if (buffer[0] == '0')  
76             return NULL;  
77     }  
78 }  
79   
80 void *read_info(int saiCId)  
81 {  
82         int n;  
83         char buffer[512];  
84   
85         if (saiCId < 0)  
86             pthread_exit((void *)1);  
87         while(1)  
88         {  
89                 bzero(buffer,512);  
90                 n = recv(saiCId,buffer,sizeof(buffer),0);  
91                 printf("From server:  %s/n", buffer);  
92                 if (n < 0)  
93                     pthread_exit((void *)1);  
94                 else  
95                     if(buffer[0]=='0')  
96                         return NULL;  
97         }  
98   
99 }
posted @ 2012-05-29 15:01  nitrogen  阅读(180)  评论(0)    收藏  举报