在网络程序里面,一般的来说都是许多客户机对应一个服务器.为了处理客户机的请求, 对服务端的程序就提出了特殊的要求.我们学习一下目前最常用的服务器模型.
循环服务器:循环服务器在同一个时刻只可以响应一个客户端的请求
并发服务器:并发服务器在同一个时刻可以响应多个客户端的请求
9.1 循环服务器:
UDP服务器
UDP循环服务器的实现非常简单:
UDP服务器每次从套接字上读取一个客户端的请求,处理, 然后将结果返回给客户机.
可以用下面的算法来实现.
socket(...);
bind(...);
while(1)
{
recvfrom(...);
process(...);
sendto(...);
}
因为UDP是非面向连接的,没有一个客户端可以老是占住服务端. 只要处理过程不是死循环, 服务器对于每一个客户机的请求总是能够满足.
9.2 循环服务器:
TCP服务器
TCP循环服务器的实现也不难:TCP服务器接受一个客户端的连接,然后处理,完成了这个客户的所有请求后,断开连接.
算法如下:
socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
while(1)
{
read(...);
process(...);
write(...);
}
close(...);
}
TCP循环服务器一次只能处理一个客户端的请求.只有在这个客户的所有请求都满足后, 服务器才可以继续后面的请求.这样如果有一个客户端占住服务器不放时,其它的客户机都不能工作了.因此,TCP服务器一般很少用循环服务器模型的.
9.3 并发服务器: TCP服务器
为了弥补循环TCP服务器的缺陷,人们又想出了并发服务器的模型. 并发服务器的思想是每一个客户机的请求并不由服务器直接处理,而是服务器创建一个 子进程来处理.
算法如下:
socket(...);
bind(...);
listen(...);
while(1)
{
accept(...);
if(fork(..)==0)
{
while(1)
{
read(...);
process(...);
write(...);
}
close(...);
exit(...);
}
close(...);
}
TCP并发服务器可以解决TCP循环服务器客户机独占服务器的情况. 不过也同时带来了一个不小的问题.
为了响应客户机的请求,服务器要创建子进程来处理. 而创建子进程是一种非常消耗资源的操作.
9.4 并发服务器:
多路复用I/O
为了解决创建子进程带来的系统资源消耗,人们又想出了多路复用I/O模型.
首先介绍一个函数select
int select(int nfds,
fd_set *readfds,fd_set *writefds,
fd_set *except fds,
struct timeval *timeout
)
void FD_SET(int fd,fd_set *fdset)
void FD_CLR(int fd,fd_set *fdset)
void FD_ZERO(fd_set *fdset)
int FD_ISSET(int fd,fd_set *fdset)
一般的来说当我们在向文件读写时,进程有可能在读写出阻塞,直到一定的条件满足.
比如我们从一个套接字读数据时,可能缓冲区里面没有数据可读(通信的对方还没有发送数据过来),
这个时候我们的读调用就会等待(阻塞)直到有数据可读.如果我们不 希望阻塞,
我们的一个选择是用select系统调用.
只要我们设置好select的各个参数,那么当文件可以读写的时候select回"通知"我们 说可以读写了.
readfds所有要读的文件 文件描述符的集合
writefds所有要写的文件 文件描述符的集合
exceptfds其他的服要向我们通知的文件描述符
timeout超时设置.
nfds所有我们监控的文件描述符中最大的那一个加1
在我们调用select时进程会一直阻塞直到以下的一种情况发生.
1)有文件可以读.
2)有文件可以写.
3)超时所设置的时间到.
为了设置文件描述符我们要使用几个宏. FD_SET将fd加入到fdset
FD_CLR将fd从fdset里面清除
FD_ZERO从fdset中清除所有的文件描述符
FD_ISSET判断fd是否在fdset集合中
使用select的一个例子
int use_select(int *readfd,int n)
{
fd_set my_readfd;
int maxfd;
int i;
maxfd=readfd[0];
for(i=1;i<n;i++)
{
if(readfd[i]>maxfd) maxfd=readfd[i];
}
while(1)
{
/* 将所有的文件描述符加入 */
FD_ZERO(&my_readfd);
for(i=0;i<n;i++)
FD_SET(readfd[i],*my_readfd);
/* 进程阻塞 */
select(maxfd+1,& my_readfd,NULL,NULL,NULL);
/* 有东西可以读了 */
for(i=0;i<n;i++)
{
if(FD_ISSET(readfd[i],&my_readfd))
{
/* 原来是我可以读了 */
we_read(readfd[i]);
}
}
}
}
使用select后我们的服务器程序就变成了.
初始话(socket,bind,listen);
while(1)
{
设置监听读写文件描述符(FD_*);
调用select;
如果是倾听套接字就绪,说明一个新的连接请求建立
{
建立连接(accept);
加入到监听文件描述符中去;
}
否则说明是一个已经连接过的描述符
{
进行操作(read或者write);
}
}
多路复用I/O可以解决资源限制的问题.着模型实际上是将UDP循环模型用在了TCP上面. 这也就带来了一些问题.如由于服务器依次处理客户的请求,所以可能会导致有的客户 会等待很久.
并发服务器: UDP服务器
人们把并发的概念用于UDP就得到了并发UDP服务器模型.
并发UDP服务器模型其实是简单的.和并发的TCP服务器模型一样是
创建一个子进程来处理的 算法和并发的TCP模型一样.
除非服务器在处理客户端的请求所用的时间比较长以外,人们实际上很少用这种模型.
分享到:
相关推荐
本篇文章旨在深入解读“黑马_Linux网络编程-网络基础-socket编程-高并发服务器”相关的核心概念和技术要点,包括网络基础知识、常用网络协议、网络应用程序设计模式以及分层模型等内容。 #### 网络基础 网络基础...
【Linux网络编程-网络基础-socket编程-高并发服务器】 在深入探讨Linux下的网络编程之前,我们首先要理解网络通信的基础概念——协议。协议是数据传输和解释的规则,它确保了不同设备之间的通信能顺利进行。例如,...
网络基础协议的概念: 在计算机网络中,协议是一系列规则和约定的集合,用于控制网络中不同设备间的通信方式。...通过深入理解这些知识点,可以更好地掌握Linux网络编程,以及如何构建高并发服务器。
Linux网络编程涉及网络基础知识,尤其是Socket编程和高并发服务器的实现。网络协议是通信的规则,比如文件传输协议FTP,它的基本流程包括三次数据传输:文件名、文件大小和文件内容。随着协议的发展和标准化,形成了...
Linux网络编程是构建高效、高并发服务器的基础,其中的核心概念之一是socket编程。Socket是操作系统提供的接口,允许应用程序进行网络通信。在这个过程中,理解和运用网络基础协议至关重要。 协议是网络通信的规则...
《Linux网络编程》一书是IT领域中关于操作系统与网络通信的经典教材,它深入探讨了在Linux环境下如何进行网络编程,涵盖了从低级socket接口到高级应用层协议的实现。这个压缩包“linux网络编程-源代码.rar”包含了该...
文档还提到了网络编程中常见的客户端/服务器模型。在这种模型中,服务器负责监听客户端的请求,并提供相应的服务;而客户端则发起请求并接收服务。 9. 网络协议 网络编程不仅仅局限于Linux环境,还涉及到多个网络...
教程名称:Linux Socket网络编程系列文档合集课程目录:【】Linux 网络编程入门教程 clown【】linux系统分析与高级编程技术【】Linux... 服务器模型【】网络 资源太大,传百度网盘了,链接在附件中,有需要的同学自取。
- **概述:** 解释了客户端/服务器模型的基本概念及其在网络中的应用。 - **知识点:** - 客户端与服务器的角色划分。 - 请求-响应模式的工作流程。 - 不同类型的网络服务示例。 **1.5 Linux的发展** - **概述:...
本资料集专注于"Linux编程技术-多线程-网络编程",它涵盖了UNIX环境高级编程、Linux网络编程、Linux多线程编程、Linux窗口编程以及Linux脚本编程等多个核心主题。这些内容都是构建高效、可靠且可扩展的Linux应用的...
此外,还要掌握套接字编程,这是网络通信的基础,包括TCP/IP协议、socket API、客户端-服务器模型等。 系统调用是Linux编程的核心,比如`fork()`用于创建新进程,`exec()`系列函数用于替换当前进程的执行体,`wait...
Linux网络基础和网络编程...对于压缩包中的"01_Linux网络编程-网络基础-socket编程-高并发服务器.pdf"文档,可以作为进一步学习和研究的参考资料,它可能详细阐述了这些概念并包含实例代码,有助于读者深化理解和应用。
此外,Linux网络编程中的一个重要概念是I/O模型,包括阻塞I/O、非阻塞I/O、I/O复用(select、poll、epoll)、信号驱动I/O和异步I/O。这些模型在处理大量并发连接时尤其关键,因为它们决定了程序如何高效地管理等待I/...
第2章 Linux编程环境 14 2.1 Linux环境下的编辑器 14 2.1.1 vim使用简介 14 2.1.2 使用vim建立文件 15 2.1.3 使用vim编辑文本 16 2.1.4 vim的格式设置 18 2.1.5 vim配置文件.vimrc 19 2.1.6 使用其他...
在Linux系统中,Socket编程是实现网络通信的基础,它提供了进程间通过网络交换数据的接口。C++ Socket库是Linux下进行网络编程的常用工具,它允许开发者利用标准的C++语言来创建复杂的网络应用程序。本资源“实战...
- **客户机/服务器模型**:描述了网络通信的基本模式,其中客户机发起请求,服务器响应请求。 #### 二、Unix/Linux发展历史与系统特性 - **Unix早期发展**:始于1970年代初的AT&T贝尔实验室,由Ken Thompson和...
在IT行业中,Linux系统编程是开发者们不可或缺的技能之一,特别是在服务器端开发和网络通信领域。本课程聚焦于“网络编程基础-socket”,是Linux系统编程的重要组成部分。Socket编程是实现网络应用程序间通信的一种...