最近在学习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越界了,但检查总是没有什么问题。
[[email protected]_62_27_centos changeBigSmall]# ./server
Accepting connections ..
Segmentation fault
[[email protected]_62_27_centos changeBigSmall]# ./client abcdef
Response from server:
[[email protected]_62_27_centos changeBigSmall]#
发现也没有出现perror()的错误还有printf一直没有打印连接的端口号,连接成功理应由成功连接的地址端口显示出来。最后对函数inet_ntoa()查询是发现要加入#include <arpa/inet.h> 的头文件。哦NO,原来没有加入相应的头文件也会引起段错误。
加上就好了。
时间: 2024-10-20 03:30:29