最近在看《UNIX网络编程》(简称unp)和《Linux程序设计》,对于unp中第一个获取服务器时间的例子,实践起来总是有点头痛的,因为作者将声明全部包含在了unp.h里,导致后面编写代码会对这个头文件造成依赖,而学习不到调用了相应功能之后,应该包含哪些确切的头文件。
再者,我下载了unp.h之后,头文件包含再次产生了其他的依赖缺失,因此便参考了《Linux程序设计》中socket一章的入门例子的头文件包含,并且编译中仍然找不到的包含或者是宏定义在unp.h中搜索并粘贴进来,从而不需要再包含类似unp.h之类的自定义头文件。
以下代码在root权限下运行,因为使用的端口号13对于非root用户可能会无权访问。
unp原书中服务器获取机器时间送回客户端,但我在运行中,字符串保存到buffer区的函数snprintf()总是造成了内存错误而中断,所以本着入门的目的,改为了复制一句话到buffer中。
/*client.c*/ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <sys/un.h> #include <unistd.h> #include <stdlib.h> #include <netinet/in.h> #define MAXLINE 4096 #define PORT 13 #define SA struct sockaddr int main(int argc, char *argv[]) { int sockfd, n; char recvline[MAXLINE+1]; struct sockaddr_in servaddr; if (argc != 2) { fprintf(stderr, "usage: client <IP>\n"); 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) { fprintf(stderr, "inet_pton error for %s\n", argv[1]); exit(1); } if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0) { fprintf(stderr, "connect error\n"); 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); } exit(0); }
/*server.c*/ #include <sys/types.h> #include <sys/socket.h> #include <stdio.h> #include <sys/un.h> #include <unistd.h> #include <stdlib.h> #include <string.h> #include <netinet/in.h> #define MAXLINE 4096 #define LISTENQ 1024 #define PORT 13 #define SA struct sockaddr int main(int argc, char *argv[]) { int listenfd, connfd; struct sockaddr_in servaddr; char buff[MAXLINE+1]; time_t t; listenfd = socket(AF_INET, SOCK_STREAM, 0); bzero(&servaddr, sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_addr.s_addr = htonl(INADDR_ANY); servaddr.sin_port = htons(PORT); bind(listenfd, (SA *) &servaddr, sizeof(servaddr)); listen(listenfd, LISTENQ); while (1) { connfd = accept(listenfd, (SA *)NULL, NULL); /* write something to buff[]*/ strcpy(buff, "this is a message\n"); write(connfd, buff, strlen(buff)); close(connfd); } exit(0); }
编译文件:
1 $ gcc client.c -o client 2 $ gcc server.c -o server
在一个窗口中运行服务器:
1 $ ./server
在另一个窗口运行客户端,从而显示出一句话"this is a message":
1 $ ./client 127.0.0.1
时间: 2024-11-11 03:11:34