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

来源:互联网 发布:电商美工工资待遇 编辑:程序博客网 时间:2024/04/19 07:45
最近在学习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_INETunsigned short int sin_port; //网络字节顺序struct in_addr sin_addr;   //struct in_addr { unsigned long s_addr; }unsigned char sin_zero[8];}

 

 

 

  

  

0 0