第十一章 网络编程
11.1 客户端-服务器编程模型
每个网络应用都是基于客户端-服务器模型的
一个应用是由一个服务器进程和一个或者多个客户端进程组成
服务器管理某种资源,并通过操作这种资源来为他的客户端提供某种服务
客户端-服务器模型中的基本操作是事务,由四步组成:
11.2 网络
客户端和服务器通常运行在不同的主机上,并且通过计算机网络的硬件和软件资源来通信
物理上而言,网络是一个按照地理远近组成的层次系统.最底层是LAN(局域网).最流行的局域网技术是以太网.每个以太网适配器都有一个全球唯一的48位地址
一台主机可以发送一段位,称为帧,到这个网段内其它任何主机
使用一些电缆和叫做网桥的小盒子,多个以太网段可以连接成较大的局域网,称为桥接以太网
每台路由器对于他所连接到的每个网络都有一个适配器(端口).路由器也能连接高速点到点电话连接,称为WAN(广域网)
如何能让某台源主机跨过所有不兼容的网络发送数据位到另一台目的主机呢?解决方法是一层运行在每台主机和路由器上的协议软件,它提供两种基本能力:(1)命名机制(2)传送机制
下图展示了一个主机和路由器如何使用互联网络协议在不兼容的局域网间传送数据的事例
11.3 全球IP因特网
全球IP因特网是最著名和最成功的互联网络实现
因特网的客户端和服务器混合使用套接字接口函数和Unix I/O函数来进行通信
从程序员的角度,因特网可以看作是一个世界范围的主机集合,满足以下特性:
(1)主机集合被映射为一组32位的IP地址
(2)这组IP地址被映射为一组称为因特网域名的标识符
(3)因特网主机上的进程能够通过连接和任何其他因特网主机上的进程通信
11.3.1 IP地址
一个IP地址就是一个32位无符号整数.网络程序将IP地址存放在下图所示的IP地址结构中
IP地址通常是以一种称为点分十进制表示法来表示的
Linux系统上,使用HOSTNAME命令来确定自己主机的点分十进制地址:linux> hostname -i
因特网程序使用inet_aton和inet_ntoa函数来实现IP地址和点分十进制之间的转换
11.3.2 因特网域名
每台因特网主机都有本地定义的域名localhost,这个域名总是映射为本地回送地址127.0.0.1:
可以使用HOSTNAME来确定本地主机的实际域名:
在最简单的情况下,一个域名和一个IP地址是一一映射的:
然而,在某些情况下,多个域名可以映射为同一个IP地址:
在最通常的情况下,多个域名可以映射到多个IP地址:
某些合法的域名没有映射到任何IP地址:
11.3.3 因特网连接
因特网客户端和服务器通过在连接上发送和接收字节流来通信,连接是点对点的,全双工的,可靠的
一个套接字是连接的一个端点.每个套接字都有相应的套接字地址,是由一个因特网地址和一个16位的整数端口组成的,用"地址:端口"来表示
当客户端发起一个连接请求时,客户端套接字地址中的端口是由内核自动分配的,称为临时端口
而服务器套接字地址中的端口通常是某个知名的端口,是和这个服务器相对应的
如图展示了一个Web客户端和一个Web服务器之间的连接
11.4 套接字接口
套接字接口是一组函数,他们和UnixI/O函数结合起来,用以创建网络应用
11.4.1 套接字地址结构
从Unix内核的角度来看,一个套接字就是通信的一个端点
从Unix程序的角度来看,套接字就是一个有相应描述符的打开文件
11.4.2 socket函数
作用:创建一个套接字描述符
11.4.3 connect函数
作用:建立和服务器的连接
11.4.4 open_clientfd函数
作用:建立和服务器的连接
11.4.5 bind函数
作用:被服务器用来和客户端建立连接
11.4.6 listen函数
服务器调用listen函数告诉内核,描述符是被服务器而不是客户端使用的
11.4.7 open_listenfd函数
服务器可以用它来创建一个监听描述符
11.4.8 accept函数
作用:等待来自客户端的连接请求
第十二章 并发编程
应用级并发在某些情况下很实用:(1)访问慢速I/O设备(2)与人交互(3)通过推迟工作以降低延迟(4)服务多个网络客户端(5)在多核机器上进行并行计算(6)进程(7)I/O多路复用(8)线程
12.1 基于进程的并发编程
一个构造并发服务器的自然方法就是,在父进程中接受客户端连接请求,然后创建一个新的子进程来为每个新客户端提供服务
12.3 基于线程的并发编程
12.3.3 创建线程
线程通过调用pthread_create函数来创建其它进程
新进程可以通过调用pthread_self函数来获得他自己的线程ID
12.3.4 终止线程
一个线程是以下列方式之一来终止的:
- 当顶层的线程例程返回时,线程会隐式的终止
- 通过调用pthread_exit函数,线程会显式的终止
- 某个对等线程调用Unix的exit函数,该函数终止进程以及所有与该进程相关的线程
- 另一个对等线程通过以当前线程ID作为参数调用pthread_cancle函数来终止当前线程
12.3.5 回收已终止线程的资源
pthread_join作用:等待其它线程终止
12.5 用信号量同步线程
12.5.1 进度图
进度图将n个并发线程的执行模型化为一条n维笛卡儿空间中的轨迹线:每条轴k对应于线程k的进度;每个点代表线程k已经完成了指令I(k)这一状态;图的原点对应于没有任何线程完成一条指令的初始状态
例如:H(1),L(1),U(1),H(2),L(2),S(1),T(1),U(2),S(2),T(2),