§有关电子资料链接:
http://www.unpbook.com/
§1.1 介绍
图 1.2 服务器同时处理多个客户端
§1.2 代码示例和解说
1 #include "unp.h"
2 int
3 main(int argc, char **argv)
4 {
5 int sockfd, n;
6 char recvline[MAXLINE + 1];
7 struct sockaddr_in servaddr;
8 if (argc != 2)
9 err_quit("usage: a.out <IPaddress>");
10 if ( (sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
11 err_sys("socket error");
12 bzero(&servaddr, sizeof(servaddr));
13 servaddr.sin_family = AF_INET;
14 servaddr.sin_port = htons(13); /* daytime server */
15 if (inet_pton(AF_INET, argv[1], &servaddr.sin_addr) <= 0)
16 err_quit("inet_pton error for %s", argv[1]);
17 if (connect(sockfd, (SA *) &servaddr, sizeof(servaddr)) < 0)
18 err_sys("connect error");
19 while ( (n = read(sockfd, recvline, MAXLINE)) > 0) {
20 recvline[n] = 0; /* null terminate */
21 if (fputs(recvline, stdout) == EOF)
22 err_sys("fputs error");
23 }
24 if (n < 0)
25 err_sys("read error");
26 exit(0);
27 }
其中unp.h是自定义的头文件,查看源代码。我们编译并执行以上代码,得到以下输出结果:
solaris %a.out 206.168.112.96 our input | |
Mon May 26 20:58:40 2003 the program's output | |
下面简要分析以上27行代码,后续章节中有更详细的讨论.
包含我们自己的头文件
1 该头文件包含了大多数网络程序所需要的多个头文件以及定义了我们将要使用的一些常量(例如 MAXLINE).
命令行参数
2–3 这是含有命令行参数的主函数定义(即main函数).我们以ANSI C标准来书写代码.
创建TCP套接字
10–11 socket函数调用创建了一个网络流套接字.(Internet (AF_INET) stream (SOCK_STREAM) socket), 该函数返回一个整数值,它描述了该套接字,以后的函数通过该整数值来使用这个套接字(例如connect和read等调用). 其中err_开头的函数是我们自定义的函数,详见这里.
确定服务器IP地址和端口号
12–16 我们填充了网络套接字地址结构(一个名为servaddr的结构体sockaddr_in),填充的信息包括服务器IP地址和端口号.我们把整个结构体首先清零,然后设置地址族为AF_INET(IPV6该项为AF_INET6),端口号为13(时间服务器的端口号,是一个大家都知道的端口号).IP地址由命令行参数指定(argv[1]).IP地址和端口号必须按照指定的格式来填充,我们通过调用htons(主机字节流到网络字节流的转换)和inet_pton(点分十进制到32位整数的转换)两个调用来进行转化到所需要的格式.
在调用inet_pton的时候可而能会遇到问题,因为这是IPv6新增的函数,以前的IPv4版本可以调用inet_addr来替代该函数.
与服务器建立一个连接
17–18 TCP套接字调用connect函数,就与服务器(main函数的第二个参数)建立了一个TCP连接,我们必须指定套接字结构体的第三个参数长度,它总是让编译器通过C的sizeof运算符来计算.
读取和显示服务器的回复
19–25 调用read来读取服务器的回复,利用标准I/O来显示该回复信息.此外,在使用TCP的时候我们必须要注意,因为它是一个没有边界的字节流协议.服务器的回复是一个26字节的串:
Mon May 26 20 : 58 : 40 2003\r\n
\r 是回车, \n 是换行.
终止程序
26 exit 终止程序.Unix在一个进程结束时候总是关闭所有打开的描述符,因此我们的TCP套接字此时关闭了.
后续内容将对此有更深入的讨论.