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

      

      

  • 相关阅读:
    Hadoop集群(三) Hbase搭建
    Hadoop集群(二) HDFS搭建
    Hadoop集群(一) Zookeeper搭建
    Redis Cluster 添加/删除 完整折腾步骤
    Redis Cluster在线迁移
    Hadoop分布式HA的安装部署
    Describe the difference between repeater, bridge and router.
    what is the “handover” and "soft handover" in mobile communication system?
    The main roles of LTE eNodeB.
    The architecture of LTE network.
  • 原文地址:https://www.cnblogs.com/wannable/p/5910968.html
Copyright © 2011-2022 走看看