十幾年沒有寫 C 了,這能夠說是從新學習,底下的程式是改寫自 W.Richard Stevens 的名著 - UNIX Network Programming Volume 1,改寫的緣由有二: (1) 在個人開發環境 scientific linux 7.0 上沒辦法正常 compile,多是因為 Stevens 的程式是在 UNIX 上寫的,與 linux 上略有不一樣; (2) Stevens 用 #define 將許多經常使用的函式從新定義,對於初學者來說,反而會被混淆,我將這些函式還原為原始函式。linux
這個程式有 client 和 server,server 先啟動,等待 client 連線,待 client 連線後回覆現在的系統時間,client 將收到的值印出。第一個程式是 server,第二個程式是 client。這裡會詳細說明每個函式,因為… 我是初學者!! socket
1 #include <sys/socket.h> 2 #include <sys/types.h> 3 #include <stdio.h> 4 #include <unistd.h> 5 #include <netinet/in.h> 6 #include <string.h> 7 #include <arpa/inet.h> 8 #include <time.h> 9 10 const int MAXLINE = 100; 11 const int LISTENQ = 1024; 12 13 int main(int argc, char **argv) { 14 int listenfd, connfd; 15 struct sockaddr_in servaddr; 16 char buff[MAXLINE]; 17 18 time_t ticks; 19 listenfd = socket(AF_INET, SOCK_STREAM, 0); 20 21 bzero(&servaddr, sizeof(servaddr)); 22 servaddr.sin_family = AF_INET; 23 servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 24 servaddr.sin_port = htons(1513); 25 26 bind(listenfd, (struct sockaddr *) &servaddr, sizeof(servaddr)); 27 listen(listenfd, LISTENQ); 28 29 for( ; ; ) { 30 connfd = accept(listenfd, (struct sockaddr *) NULL, NULL); 31 32 ticks = time(NULL); 33 snprintf(buff, sizeof(buff), "%.24s\r\n", ctime(&ticks)); 34 write(connfd, buff, strlen(buff)); 35 36 close(connfd); 37 } 38 39 }
1 #include <stdio.h> 2 #include <sys/socket.h> 3 #include <sys/types.h> 4 #include <netinet/in.h> 5 #include <strings.h> 6 #include <arpa/inet.h> 7 8 const int MAXLINE = 100; 9 10 void err_sys(const char* x, ...) 11 { 12 perror(x); 13 //exit(1); 14 } 15 16 void err_quit(const char* x, ...) 17 { 18 perror(x); 19 //exit(1); 20 } 21 22 int main(int argc, char **argv) 23 { 24 int sockfd, n; 25 char recvline[MAXLINE + 1]; 26 struct sockaddr_in servaddr; 27 28 if (argc != 2) { 29 err_quit("usage: a.out <IPaddress>"); 30 return 1; 31 } 32 33 if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) { 34 err_sys("socket error"); 35 return 1; 36 } 37 38 bzero(&servaddr, sizeof(servaddr)); 39 servaddr.sin_family = AF_INET; 40 servaddr.sin_port = htons(1513); 41 if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0) 42 err_quit("inet_pton error for %s", argv[1]); 43 44 if (connect(sockfd, (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0) 45 err_sys("connect error"); 46 47 while ((n = read(sockfd, recvline, MAXLINE)) > 0) { 48 recvline[n] = 0; 49 if (fputs(recvline, stdout) == EOF) 50 err_sys("fputs error"); 51 } 52 53 if (n < 0) { 54 err_sys("read error"); 55 return 1; 56 } 57 58 return 0; 59 }
測試時,先執行 server 再執行 client,client 端顯示以下結果:ui