標籤:socket 64位 linux
源碼:
/* File Name: server.c */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> //Ineternet address family #include<arpa/inet.h> #define DEFAULT_PORT 8000 #define MAXLINE 4096 int main(int argc, char** argv) { int socket_fd, connect_fd; struct sockaddr_in servaddr; char buff[4096]; int n; //初始化Socket if( (socket_fd = socket(AF_INET, SOCK_STREAM, 0)) == -1 ){ printf("create socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } //初始化 memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY);//IP地址設定成INADDR_ANY,讓系統自動擷取原生IP地址。 servaddr.sin_port = htons(DEFAULT_PORT);//設定的連接埠為DEFAULT_PORT //將本地地址綁定到所建立的通訊端上 if( bind(socket_fd, (struct sockaddr*)&servaddr, sizeof(servaddr)) == -1){ printf("bind socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } //開始監聽是否有用戶端串連 if( listen(socket_fd, 10) == -1){ printf("listen socket error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("======waiting for client's request======\n"); while(1){ struct sockaddr_in cilent_addr; //用戶端socket地址結構socklen_t length = sizeof(cilent_addr); //阻塞直到有用戶端串連,不然多浪費CPU資源。 if( (connect_fd = accept(socket_fd, (struct sockaddr*)&cilent_addr, &length)) == -1){ //用戶端的socket地址結構會填寫到cilent_addr結構體中 printf("accept socket error: %s(errno: %d)",strerror(errno),errno); continue; } //接受用戶端傳過來的資料 n = recv(connect_fd, buff, MAXLINE, 0); if( n < 0 ){printf("Server Receive Data Faild!\n");break;} //向用戶端發送回應資料 if(!fork()){ /*子進程*/ if(send(connect_fd, "Hello,you are connected!\n", 26,0) == -1) perror("send error"); close(connect_fd); exit(0); } buff[n] = '\0'; printf("recv msg from client: %s\n", buff); printf("has a cilent connect ip %s!\n", inet_ntoa(cilent_addr.sin_addr)); //列印出用戶端地址資訊 close(connect_fd); } close(socket_fd); }
/* File Name: client.c */ #include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> #include<sys/types.h> #include<sys/socket.h> #include<netinet/in.h> #define MAXLINE 4096 int main(int argc, char** argv) { int sockfd, n,rec_len; char recvline[4096], sendline[4096]; char buf[MAXLINE]; struct sockaddr_in servaddr; if( argc != 2){ printf("usage: ./client <ipaddress>\n"); exit(0); } if( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0){ printf("create socket error: %s(errno: %d)\n", strerror(errno),errno); exit(0); } memset(&servaddr, 0, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(8000); if( inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0){ printf("inet_pton error for %s\n",argv[1]); exit(0); } if( connect(sockfd, (struct sockaddr*)&servaddr, sizeof(servaddr)) < 0){ printf("connect error: %s(errno: %d)\n",strerror(errno),errno); exit(0); } printf("send msg to server: \n"); fgets(sendline, 4096, stdin); if( send(sockfd, sendline, strlen(sendline), 0) < 0) { printf("send msg error: %s(errno: %d)\n", strerror(errno), errno); exit(0); } if((rec_len = recv(sockfd, buf, MAXLINE,0)) == -1) { perror("recv error"); exit(1); } buf[rec_len] = '\0'; printf("Received : %s ",buf); close(sockfd); exit(1); }
遇到到問題:
64位Centos下使用inet_ntoa()端錯誤:
Segmentation fault (core dumped)
32位正常列印,64位卻是段錯誤,錯在haddrp這個參數上,報錯內容是說inet_ntoa的返回值是int,因此%s無法輸出。
解決方案:
1. 如果用inet_ntoa()的話需要#include <arpa/inet.h> ,就正常了。
2. 使用inet_ntop()
最後通過arm-linux-gcc交叉編譯server端 移植到開發板 工作正常。
Centos 64下實現socket通訊