arpa/inet.h所引起的Segmentation fault及网络编程常见的头文件

  最近在学习Linux网络编程方面的知识,感觉还是有些困难。主要是对协议过程的理解,还有socket的API的理解不够深刻。今天复习编写了一个TCP的服务端和客户端的程序实现client.c从命令行参数中获得一个字符串发给服务器,然后接收服务器返回的已处理的字符串并打印。

  

  server.c

 1 #include <stdio.h>                                                                                                                  
 2 #include <stdlib.h>                                                                                                                 
 3 #include <string.h>                                                                                                                 
 4 #include <unistd.h>                                                                                                                 
 5 #include <sys/socket.h>                                                                                                             
 6 #include <netinet/in.h>                                                                                                             
 7 #include <arpa/inet.h>                                                                                                            
 8                                                                                                                                     
 9 #define MAXLINE 80                                                                                                                  
10 #define SERV_PORT 8000                                                                                                              
11                                                                                                                                     
12 int main(void)                                                                                                                      
13 {                                                                                                                                   
14     struct sockaddr_in servaddr,cliaddr;   //IPV4的地址结构                                                                               
15     socklen_t cliaddr_len;                                                                                                            
16     int listenfd,connfd;                                                                                                              
17     char buf[MAXLINE];                                                                                                                
18     char str[INET_ADDRSTRLEN];                                                                                                        
19     int i,n;                                                                                                                          
20                                                                                                                                       
21     if(-1 == (listenfd =  socket(AF_INET,SOCK_STREAM,0)))   //对于IPV4的family的参数为AF_INET for TCP SOCK_STREAM 表示面向流的传输协议
22     {                                                                                                                                 
23         perror("socket Error");                                                                                                         
24         exit(1);                                                                                                                        
25     }                                                                                                                                 
26     bzero(&servaddr,sizeof(servaddr));                     //对于UDP协议 type is SOCK_DGRAM  表示面向数据报的传输协议   protocol指定为零        
27     servaddr.sin_family = AF_INET;               //设置地址类型                                                                       
28     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//网络地址为INADDR_ANY                                                               
29     servaddr.sin_port = htons(SERV_PORT);        //端口号为SERV_PORT 定义为8000                                                       
30                                                                                                                                       
31     if(-1 == bind(listenfd,(struct sockaddr *)&servaddr,sizeof(servaddr)))                                                            
32     {                                                                                                                                 
33         perror("Bind error");                                                                                                           
34         exit(1);                                                                                                                        
35     }                                                                                                                                 
36                                                                                                                                       
37     if( -1 == listen(listenfd,20))                                                                                                    
38     {                                                                                                                                 
39         perror("Listen error");                                                                                                         
40         exit(1);                                                                                                                        
41     }                                                                                                                                 
42                                                                                                                                       
43     printf("Accepting connections ..\n");                                                                                             
44                                                                                                                                       
45     while(1){                                                                                                                         
46         cliaddr_len = sizeof(struct sockaddr_in);                                                                                       
47         if( -1 == (connfd = accept(listenfd,(struct sockaddr*)&cliaddr,&cliaddr_len)))                                                  
48         {                                                                                                                               
49             perror("Accept error");                                                                                                       
50             exit(1);                                                                                                                      
51         }                                                                                                                               
52                                                                                                                                         
53         if(-1 ==(n = read(connfd,buf,MAXLINE)))                                                                                         
54         {                                                                                                                               
55             perror("read error");                                                                                                         
56             exit(1);                                                                                                                      
57         }                                                                                                                               
58         printf("Connect from %s:%u ...!\n",inet_ntoa(cliaddr.sin_addr),ntohs(cliaddr.sin_port));                                        
59                                                                                                                                     
60     for (i = 0; i < n; i++)                                                                                                         
61         buf[i] = toupper(buf[i]);                                                                                                     
62     write(connfd, buf, n);                                                                                                          
63                                                                                                                                     
64         close(connfd);                                                                                                                  
65     }                                                                                                                                 
66     close(listenfd);                                                                                                                  
67     exit(0);                                                                                                                          
68 }                                                                                                                                   

  client.c

 1 #include <stdio.h>                                              
 2 #include <stdlib.h>                                             
 3 #include <string.h>                                             
 4 #include <unistd.h>                                             
 5 #include <sys/socket.h>                                         
 6 #include <netinet/in.h>                                         
 7                                                                 
 8 #define MAXLINE 80                                              
 9 #define SERV_PORT 8000                                          
10                                                                 
11 int main(int argc,char **argv)                                  
12 {                                                               
13     struct sockaddr_in servaddr;                                  
14     char buf[MAXLINE];                                            
15     int sockfd,n;                                                 
16     char *str;                                                    
17                                                                   
18     if(argc != 2)                                                 
19     {                                                             
20         fputs("Usage: ./client message\n",stderr);                  
21         exit(1);                                                    
22     }                                                             
23     str = argv[1];                                                
24     sockfd = socket(AF_INET,SOCK_STREAM,0);                       
25     bzero(&servaddr,sizeof(servaddr));                            
26     servaddr.sin_family = AF_INET;                                
27     inet_pton(AF_INET,"127.0.0.1",&servaddr.sin_addr);            
28     servaddr.sin_port = htons(SERV_PORT);                         
29                                                                   
30     connect(sockfd,(struct sockaddr*)&servaddr,sizeof(servaddr)); 
31     write(sockfd,str,strlen(str));                                
32     n = read(sockfd,buf,MAXLINE);                                 
33     printf("Response from server:\n");                            
34                                                                   
35     //if(-1 == read(sockfd,buf,1024)){                            
36     //     perror("Recv Error:");                                 
37     //}                                                           
38     write(STDOUT_FILENO, buf, n);                                 
39                                                                   
40   close(sockfd);                                                
41     return 0;                                                     
42 }                                                               

  但是发现一直有个Segmentation fault显示没有返回正确的结果,一开始还以为是数组buf越界了,但检查总是没有什么问题。

[root@VM_62_27_centos changeBigSmall]# ./server
Accepting connections ..
Segmentation fault

[root@VM_62_27_centos changeBigSmall]# ./client abcdef
Response from server:
[root@VM_62_27_centos changeBigSmall]#

  发现也没有出现perror()的错误还有printf一直没有打印连接的端口号,连接成功理应由成功连接的地址端口显示出来。最后对函数inet_ntoa()查询是发现要加入<arpa/inet.h> 的头文件。哦NO,原来没有加入相应的头文件也会引起段错误。

  加上就好了<arpa/inet.h>的头文件就好了

[root@VM_62_27_centos changeBigSmall]# ./client abcd
Response from server:
ABCD[root@VM_62_27_centos changeBigSmall]#

  那经过此次教训之后,还是总结一下网络编程中常见的头文件。

 1 sys/types.h:数据类型定义
 2  
 3 sys/socket.h:提供socket函数及数据结构
 4  
 5 netinet/in.h:定义数据结构sockaddr_in
 6  
 7 arpa/inet.h:提供IP地址转换函数
 8  
 9 netdb.h:提供设置及获取域名的函数
10  
11 sys/ioctl.h:提供对I/O控制的函数
12  
13 sys/poll.h:提供socket等待测试机制的函数

  其他常见的头文件

unistd.h:提供通用的文件、目录、程序及进程操作的函数
 
errno.h:提供错误号errno的定义,用于错误处理
 
fcntl.h:提供对文件控制的函数
 
time.h:提供有关时间的函数
 
crypt.h:提供使用DES加密算法的加密函数
 
pwd.h:提供对/etc/passwd文件访问的函数
 
shadow.h:提供对/etc/shadow文件访问的函数
 
pthread.h:提供多线程操作的函数
 
signal.h:提供对信号操作的函数
 
sys/wait.h、sys/ipc.h、sys/shm.h:提供进程等待、进程间通讯(IPC)及共享内存的函数

  还有一些常见的结构体

struct sockadd {
unsigned short sa_family;
char sa_data[14];
}

struct sockaddr_in {
short int sin_family;  //AF_INET
unsigned short int sin_port; //网络字节顺序
struct in_addr sin_addr;   //struct in_addr { unsigned long s_addr; }
unsigned char sin_zero[8];
}

 

 

 

  

  

posted @ 2016-09-26 22:24  disdader  阅读(7068)  评论(0编辑  收藏  举报