服务器软件设计概论
服务器的设计主要有以下三个方面:
传输协议:无连接和面向连接的访问
状态信息:无状态的和有状态的服务器
并发性:循环和并发服务器的实现
我们首先要有一个服务器设计算法,才能设计出服务器软件
概念性的服务器算法(最简单的)
1.创建一个套接字,将它绑定到一个熟知的端口上,并期望在这个端口上接受请求
2.进入无限循环,在该循环中,服务器接受来自客户的请求
3.处理这一请求,构造应答,然后将这个应答发回给客户
四种基本类型的服务器
一种循环的、面向连接的服务器的算法
1.创建套接字并将其绑定到他所提供服务的熟知端口上
2.将该端口设置为被动模式,使其准备为服务器所用
3.从该套接字上接受下一个连接请求,获得该连接的套接字
4.重复地读取来自客户的需求,构造响应,按照应用协议向客户发回响应;
5.当与某个特定客户完成交互时,关闭连接,并返回步骤3以接受新的连接。
循环的、无连接的服务器的算法
创建套接字并将其绑定到所提供服务的熟知端口上
重复地读取来自客户的请求,构造响应,按照应用协议向客户发回响应
并发的、无连接的服务器的算法
1.主1 创建套接字并将其绑定到所提供服务的熟知地址上。让该套接字保持为未连接的
2.主2 反复调用recvfrom接受来自客户的下一个请求,创建一个新的从进程(可能在一个新进程中)来处理响应
3.从1 从来自主进程的特定请求以及到该套接字的访问开始
4.从2 根据应用协议构造应答,并用sendto将该应答发回客户
5.从3 退出
并发的、面向连接服务器的算法
1.主1 创建套接字并将其绑定到所提供服务的熟知地址上。让该套接字保持非连接
2.主2 将该端口设置为被动模式,使其准备为服务器所用
3.主3 反复调用accept以便接受来自客户的下一个连接请求,并创建新的从线程或进程来处理响应
4.从1 由主进程传递来的连接请求(即针对连接的套接字)开始
5.从2 用该连接与客户进行交互:读取请求并发回响应
6.从3 关闭连接并退出。在处理完来自客户的所有请求后,从线程就退出
另外,单线程异步IO也能实现表面上的并发
1.创建套接字S并将其绑定到所提供服务的熟知端口上。将该套接字加到一个表中,该表中的项是可以进行I/O的描述符
2.使用select在已有的套接字上等待I/O
3.如果S准备就绪,使用accept获得下一个连接,并将这个新的套接字NSi加入到表中,该表中的项是可以进行I/O的描述符
4.如果是S以外的某些套接字准备就绪,就使用recv或read获得下一个请求,构造响应,用send或write将响应发回给客户
5.继续按照以上的步骤2进行处理
服务器设计算法选择要根据具体的应用和环境,但是服务器都会出现死锁的困扰,为什么会出现死锁?
如果服务器与客户通信使用了可能会阻塞的系统调用,一个不能正常工作的客户可能会引起单线程服务器死锁。在服务器中,死锁是一个严重的问题,因为它意味着一个客户的行为会使服务器不能处理其他客户的请求