zoukankan      html  css  js  c++  java
  • 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 ..
    ");                                                                                             
    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 ...!
    ",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
    ",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:
    ");                            
    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];
    }

      

      

  • 相关阅读:
    python的三个函数map、filter、reduce详解
    python 对文件进行切分行
    sed 命令匹配行操作
    停止学习框架
    JS中双等号“==”使用情况
    JavaScript中数组迭代方法
    JavaScript中replace()方法的第二个参数解析
    Vue生命周期
    JS中浮点数精度误差解决
    大量DOM操作的解决方案
  • 原文地址:https://www.cnblogs.com/wannable/p/5910968.html
Copyright © 2011-2022 走看看