最近在看《UNIX網絡編程》(簡稱unp)和《Linux程序設計》,對於unp中第一個獲取服務器時間的例子,實踐起來老是有點頭痛的,由於做者將聲明所有包含在了unp.h裏,致使後面編寫代碼會對這個頭文件形成依賴,而學習不到調用了相應功能以後,應該包含哪些確切的頭文件。編程
再者,我下載了unp.h以後,頭文件包含再次產生了其餘的依賴缺失,所以便參考了《Linux程序設計》中socket一章的入門例子的頭文件包含,而且編譯中仍然找不到的包含或者是宏定義在unp.h中搜索並粘貼進來,從而不須要再包含相似unp.h之類的自定義頭文件。服務器
如下代碼在root權限下運行,由於使用的端口號13對於非root用戶可能會無權訪問。網絡
unp原書中服務器獲取機器時間送回客戶端,但我在運行中,字符串保存到buffer區的函數snprintf()老是形成了內存錯誤而中斷,因此本着入門的目的,改成了複製一句話到buffer中。socket
/*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":this
1 $ ./client 127.0.0.1