作者:小馨小慧 | 来源:互联网 | 2023-08-31 09:36
前言本文将讲解一对经典的客户服务器回射程序,感受网络编程的大致框架(该程序稍作改装即可演变成各种提供其他服务的程序);同时,还将对其运行过程加以分析,观察程序背后协议的执行细节
>前言
本文将讲解一对经典的客户/服务器回射程序,感受网络编程的大致框架( 该程序稍作改装即可演变成各种提供其他服务的程序
);同时,还将对其运行过程加以分析,观察程序背后协议的执行细节,学习调试网络程序的技巧。
>客户端
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 ");
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 void
32 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 void
41 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 }