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];
}

 

 

 

  

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM