// 从服务器读取时间 // client.c #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> // exit #include <netinet/in.h> // socketaddr_in #include <strings.h> // bzero #include <arpa/inet.h> // inet_pton #include <unistd.h> // read #define MAXLINE 4096 /* max text line length */ #define PORT 8888 int main(int argc, char ** argv) { int sockfd, n; char recvline[MAXLINE + 1]; struct sockaddr_in servaddr; if (argc != 2) { fprintf(stderr, "Usage: %s IP\n", argv[0]); exit(1); } // 创建套接字 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { fprintf(stderr, "socket error\n"); exit(1); } bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(PORT); // 端口号使用网络字节序 if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <=0) {// 将ip地址由字符串,转换位2进制 fprintf(stderr, "inet_pton error for: %s", argv[1]); exit(1); } // 连接服务器, 后续使用该套接字进行通信 if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) { fprintf(stderr, "connect error: %s\n", argv[1]); perror("connect error:"); exit(1); } // 与服务器进行通信 while( (n = read(sockfd, recvline, MAXLINE)) > 0) { recvline[n] = 0; if (fputs(recvline, stdout) == EOF) { fprintf(stderr, "fputs error\n"); exit(1); } } if(n < 0) { fprintf(stderr, "read error\n"); exit(1); } return 0; }
// server.c #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <stdlib.h> // exit #include <netinet/in.h> // socketaddr_in #include <strings.h> // bzero #include <arpa/inet.h> // inet_pton #include <unistd.h> // read #include <time.h> // time #include <string.h> // strlen #define MAXLINE 4096 /* max text line length */ #define PORT 8888 int main(int argc, char ** argv) { struct sockaddr_in servaddr; int listenfd, connfd; char buff[MAXLINE]; time_t ticks; // 创建套接字 listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; // INADDR_ANY : 如果服务器有多个网络接口,那么服务器可以在任意网络接口上接受客户连接 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); // 将该套接字与地址绑定 bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); // 把该套接字,变成监听套接字 // 这样,来自客户到外来连接就可以在该套接字上由内核接受 // socket, bind, listen 是TCP服务器准备“监听套接字” 的正常步骤 listen(listenfd, 5); for(;;) { // 服务器睡眠,等待客户端连接 // 经过 TCP 3次握手 // 返回一个 “已连接描述符” connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); // 发送时间给客户端 ticks = time(NULL); snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); write(connfd, buff, strlen(buff)); // 关闭连接 close(connfd); } return 0; }
遇到的问题
error: storage size of ‘servaddr’ isn’t known struct sockaddr_in servaddr;
添加头文件: netinet/in.h
#include <netinet/in.h>
see $ man 7 ip for more help