首页 > 代码库 > 第十篇:基于TCP的一对回射客户/服务器程序及其运行过程分析( 上 )

第十篇:基于TCP的一对回射客户/服务器程序及其运行过程分析( 上 )

前言

       本文将讲解一对经典的客户/服务器回射程序,感受网络编程的大致框架( 该程序稍作改装即可演变成各种提供其他服务的程序 );同时,还将对其运行过程加以分析,观察程序背后协议的执行细节,学习调试网络程序的技巧。

客户端

 1 #include    "unp.h" 2  3 void str_cli(FILE *fp, int sockfd); 4  5 int 6 main(int argc, char **argv) 7 { 8     int                    sockfd; 9     struct sockaddr_in    servaddr;10 11     if (argc != 2)12         err_quit("usage: tcpcli <IPaddress>");13 14     sockfd = Socket(AF_INET, SOCK_STREAM, 0);15 16     bzero(&servaddr, sizeof(servaddr));17     servaddr.sin_family = AF_INET;18     servaddr.sin_port = htons(SERV_PORT);19     Inet_pton(AF_INET, argv[1], &servaddr.sin_addr);20 21     Connect(sockfd, (SA *) &servaddr, sizeof(servaddr));22 23     str_cli(stdin, sockfd);    24 25     exit(0);26 }27 28 /*29  * 事务函数30 */31 void32 str_cli(FILE *fp, int sockfd)33 {34     char    sendline[MAXLINE], recvline[MAXLINE];35 36     // 从标准输入读取字符串( 阻塞于用户 )    37     while (Fgets(sendline, MAXLINE, fp) != NULL) {38 39         // 往缓冲区写入字符串40         Writen(sockfd, sendline, strlen(sendline));41 42         // 从缓冲区读取字符串( 阻塞于服务器传回的数据 )43         if (Readline(sockfd, recvline, MAXLINE) == 0)44             err_quit("str_cli: server terminated prematurely");45 46         // 读取从服务器回射的消息并在终端打印47         Fputs(recvline, stdout);48     }49 }

服务器端

 1 #include    "unp.h" 2  3 void str_echo(int sockfd); 4  5 int 6 main(int argc, char **argv) 7 { 8     int                    listenfd, connfd; 9     pid_t                childpid;10     socklen_t            clilen;11     struct sockaddr_in    cliaddr, servaddr;12 13     listenfd = Socket(AF_INET, SOCK_STREAM, 0);14 15     bzero(&servaddr, sizeof(servaddr));16     servaddr.sin_family      = AF_INET;17     servaddr.sin_addr.s_addr = htonl(INADDR_ANY);18     servaddr.sin_port        = htons(SERV_PORT);19 20     Bind(listenfd, (SA *) &servaddr, sizeof(servaddr));21 22     Listen(listenfd, LISTENQ);23 24     for ( ; ; ) {25         clilen = sizeof(cliaddr);26         connfd = Accept(listenfd, (SA *) &cliaddr, &clilen);27 28         if ( (childpid = Fork()) == 0) {    /* 子进程处理段 */29             Close(listenfd);    /* 关闭监听套接字 */30             str_echo(connfd);    /* 事务处理 */31             exit(0);32         }33         Close(connfd);            /* 父进程关闭连接套接字 */34     }35 }36 37 /*38  * 事务处理函数39 */40 void41 str_echo(int sockfd)42 {43     ssize_t        n;44     char        buf[MAXLINE];45 46 again:47     while ( (n = read(sockfd, buf, MAXLINE)) > 0)48         Writen(sockfd, buf, n);49 50     if (n < 0 && errno == EINTR)51         goto again;52     else if (n < 0)53         err_sys("str_echo: read error");54 }

第十篇:基于TCP的一对回射客户/服务器程序及其运行过程分析( 上 )