求教面向大规模连接的高并发网络模型,该如何处理

求教面向大规模连接的高并发网络模型,该如何处理,第1张

所谓并发服务器就是在同一个时刻可以处理来自多个客户的请求循环服务器是指服务器在同一时刻只可以响应一个客户端的请求。而且对于TCP和UDP套接字,这两种服务器的实现方式也有不同的特点。

1、TCP循环服务器:

首先TCP服务器接受一个客户端的连接请求,处理连接请求,在完成这个客户端的所有请求后断开连接,然后再接受下一个客户端的请求。创建TCP循环服务器的算法如下:

复制代码 代码如下:

socket(……)//创建一个TCP套接字

bind(……)//邦定公认的端口号

listen(……)//倾听客户端连接

while(1) //开始循环接收客户端连接

{

accept(……)//接收当前客户端的连接

while(1)

{ //处理当前客户端的请求

read(……)

process(……)

write(……)

}

close(……)//关闭当前客户端的连接,准备接收下一个客户端连接

}

TCP循环服务器一次只处理一个客户端的请求,如果有一个客户端占用服务器不放时,其它的客户机连接请求都得不到及时的响应。因此,TCP服务器一般很少用循环服务器模型的。

2、TCP并发服务器:

并发服务器的思想是每一个客户端的请求并不由服务器的主进程直接处理,而是服务器主进程创建一个子进程来处理。创建TCP并发服务器的算法如下:

复制代码 代码如下:

socket(……)//创建一个TCP套接字

bind(……)//邦定公认的端口号

listen(……)//倾听客户端连接

while(1) //开始循环接收客户端的接收

{

accept(……)//接收一个客户端的连接

if(fork(……)==0) //创建子进程

{

while(1)

{ //子进程处理某个客户端的连接

read(……)

process(……)

write(……)

}

close(……)//关闭子进程处理的客户端连接

exit(……) //终止该子进程

}

close(……)//父进程关闭连接套接字描述符,准备接收下一个客户端连接

}

TCP并发服务器可以解决TCP循环服务器客户端独占服务器的情况。但同时也带来了一个不小的问题,即响应客户机的请求,服务器要创建子进程来处理,而创建子进程是一种非常消耗资源的操作。

3、UDP循环服务器:

UDP服务器每次从套接字上读取一个客户端的数据报请求,处理接收到的UDP数据报,然后将结果返回给客户机。创建UDP循环服务器的算法如下:

1 socket(……)//创建一个数据报类型的套接字 2 bind(……)//邦定公认的短口号 3 while(1) //开始接收客户端的连接 4 { //接收和处理客户端的UDP数据报 5 recvfrom(……)6 process(……)7 sendto(……)//准备接收下一个客户机的数据报 8 }

消除行号

因为UDP是非面向连接的,没有一个客户端可以独占服务器。只要处理过程不是死循环,服务器对于每一个客户机的请求总是能够处理的。

UDP循环服务器在数据报流量过大时由于处理任务繁重可能造成客户技数据报丢失,但是因为UDP协议本身不保证数据报可靠到达,所以UDP协议是允许丢失数据报的。

鉴于以上两点,一般的UDP服务器采用循环方式4、UDP并发服务器把并发的概念应用UDP就得到了并发UDP服务器,和并发TCP服务器模型一样是创建子进程来处理的。

创建UDP并发服务器的算法如下:

复制代码 代码如下:

socket(……)//创建一个数据报类型的套接字

bind(……)//邦定公认的短口号

while(1) //开始接收客户端的连接

{ //接收和处理客户端的UDP数据报

recvfrom(……)

if(fork(……)==0) //创建子进程

{

rocess(……)

sendto(……)

}

}

除非服务器在处理客户端的请求所用的时间比较长以外,人们实际上很少用这种UDP并发服务器模型的。

4、多路复用I/O并发服务器:

创建子进程会带来系统资源的大量消耗,为了解决这个问题,采用多路复用I/O模型的并发服务器。采用select函数创建多路复用I/O模型的并发服务器的算法如下:

初始化(socket,bind,listen)

复制代码 代码如下:

while(1)

{

设置监听读写文件描述符(FD_*)

调用select

如果是倾听套接字就绪,说明一个新的连接请求建立

{

建立连接(accept)

加入到监听文件描述符中去

}

否则说明是一个已经连接过的描述符

{

进行操作(read或者write)

}

多路复用I/O可以解决资源限制问题,此模型实际上是将UDP循环模型用在了TCP上面。这也会带了一些问题,如由于服务器依次处理客户的请求,所以可能导致友的客户会等待很久。

1、基本概念

n客户/服务器模型是所有网络应用的基础。客户/服务器分别指参与一次通信的两个应用实体,客户方主动地发起通信请求,服务器方被动地等待通信的建立。

2、客户软件

任何一个应用程序当需要进行远程访问时成为客户,这个应用程序也要完成一些本地的计算;

一般运行于用户的个人计算机上;

向服务器主动发起通信请求;

可以访问多个服务器,但一次只能访问一个;

不需要特殊的硬件和复杂的操作系统。

3、服务器软件

是专用的提供某种服务的特权程序,可以同时处理多个远程客户;

一般在系统启动时被执行,并连续运行以处理多次会话;

被动的等待远程客户发起通信;

需要特殊的硬件和复杂的操作系统。

数据在客户和服务器之间是双向流动的,一般是客户发出请求,服务器给出响应。

4、服务器软件的并发性

由于服务器软件要支持多个客户的同时访问,它必须具备并发性。服务器软件为每个新到的客户创建一个进程或线程来处理和这个客户的通信。服务器方传送层实体使用客户的源端口号和服务的端口号来确定正确的服务器软件进程(线程)。

5、服务器软件的组成

服务器软件一般分为两部分:一部分用于接受请求并创建新的进程或线程,另一部分用于处理实际的通信过程。

6、客户/服务器之间使用的传送层协议

可以是基于连接的TCP协议,要求建立和释放连接,适用于可靠的交互过程;

也可以是无连接的UDP协议,适用于可靠性要求不高的或实时的交互过程;

同时使用TCP和UDP的服务,有两种服务器软件的实现或服务器软件同时和TCP、UDP协议交互,不对客户做限制。

7、客户和服务器的交互

1)支持协议:在INTERNET中,客户和服务器的交互通过使用TCP/IP协议栈来完成。因此,客户和服务器所在的机器要求支持完全的协议栈。客户/服务器通过套接字访问传送层服务。

2)多种服务:一台计算机上可以运行多个服务器软件,但是要求计算机有强大的硬件资源(服务器级别的计算机)和多任务操作系统(UNIX和WIN95/98/2000/NT)。

3)服务的标识:客户是通过服务的标识来访问某种服务的,比如在INTERNET中,服务是用端口号来标识,UNIX在/etc/services文件中定义。服务器软件启动时将其标识通知传送层实体。

UDP2000个客户端左右 并发

单个数据包最大512字节

Internet 10MB带宽

要求效率(尽可能快,尽可能少丢包),这种情况下用哪种通讯模型比较有优势!

想用IOCP,因为和select模型相比,这个稍微熟悉一点,也在项目中用过,不过是TCP的。

有两个问题,大家懂得的帮忙给指导一下:

是否可以理解为UDP模式下,一次recvfrom 只对应一次sendto。

2.能否对服务端的套接字同时投递多个WsaRecvFrom,能否在多个线程中同时投递WsaSendTo和WsaRecvFrom。

------解决方案--------------------------------------------------------

-------------------------------------

等不到,包被截断了。

2.能否对服务端的套接字同时投递多个WsaRecvFrom,能否在多个线程中同时投递WsaSendTo和WsaRecvFrom。

--------------------------

其实,我个人认为对udp而言,不用iocp也可以满足。 首先sendto都是立即完成的,无需异步操作。而recvfrom可以只需阻塞一个线程就够了,不需要重叠操作。

------解决方案--------------------------------------------------------

用UDX协议最可靠,效率高,开发简单,非开源。

UDT开源,对于你这种2000客户,够用,开源。

------解决方案--------------------------------------------------------

1.sendto 10k,接受部分要么收到10k,要么全部丢失,不会出现部分收到的情况。

------解决方案--------------------------------------------------------

-------------------------------------

在局域网可以,公网,一般1K也收不到。

2.能否对服务端的套接字同时投递多个WsaRecvFrom,能否在多个线程中同时投递WsaSendTo和WsaRecvFrom。

--------------------------完全可以

------解决方案--------------------------------------------------------

1.如果UDP数据在传输过程中被分包,则你需要对数据包进行标识,已确保获取的包完整。一次recvfrom并不对应一次sendto,考虑UDP不可靠传输的因素。

2.不可以,因为sendto和recvfrom都是对同一个资源Socket进行操作。如果在多个线程中对同一个资源进行操作,如果不加锁的情况下,会非常可怕的。而且,如果你加锁了,其实还不如单线程操作。

按照你的需求最好还是采用UDP,不过可以考虑组播。

2.API调用完全没有问题。但是接到的数据可能和发送的数据次序不一样,这本身是UDP乱序特性决定了的。而且你发送方可能是多线程,从API层面来说,这些调用都是可以的,完全没有问题。但是给你接收方处理带来一系列问题。


欢迎分享,转载请注明来源:夏雨云

原文地址:https://www.xiayuyun.com/zonghe/305217.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-27
下一篇2023-04-27

发表评论

登录后才能评论

评论列表(0条)

    保存