网络小计2

1.对于要处理众多小连接的服务器,需要投递更多的AcceptEx

检查系统是否有足够AcceptEx的一个方法是:

WSAEventSelect关联到FD_ACCEPT,如果有连接到来而没有足够的AcceptEx时,注册事件会被触发


AcceptEx的一个好处是:接收连接同时会接受数据,For servers whose clients send an initial request this is ideal

但,除非AcceptEx接收到至少一个字节,否则the AcceptEx operation will not complete ,所以需要循环检查所有的连接时间,

call getsockopt with SO_CONNECT_TIME, which will return regardless of whether the socket is actually connected. If it is connected, the return value is greater than zero. A value of -1 indicates it is not connected

警告:

 As a word of warning, applications should not under any circumstances close a client socket handle used in anAcceptEx call that has not been accepted because it can lead to memory leaks. For performance reasons, the kernel-mode structures associated with anAcceptEx call will not be cleaned up when the unconnected client handle is closed until a new client connection is established or until the listening socket is closed.

警告:

虽然在完成端口的线程中投递AcceptEx看起来比较简单,也符合逻辑,但你应该避免这样做。

另外,工作线程中应该避免任何复杂的运算,让工作线程更快的处理事件

原因:

创建套接字是expensive的,因为WInsock2.0的有多层结构,当服务器创建一个套接字时,要层层调用。

所以,服务器应该在一个单独的线程里面创建套接字和投递AcceptEx,When an overlapped AcceptEx completes in the worker thread, an event can be used to signal the accept issuing thread.


Data Transfers:

默认情况下,每一个套接字都有一个发送和接收缓冲区

发送:

如果协议发送缓冲区满了,程序的发送缓冲区将被锁定,send调用将返回WSA_IO_PENDING

在处理完发送缓冲区的数据后(例如,将数据交给下层TCP处理),winsock将直接处理锁定的缓冲区,也就是说,应用程序将从缓冲区直接把数据交给TCP,绕过套接字的发送缓冲区

接收:

如果套接字的接收缓冲区是空的,当overlapped receive被调用时,程序的缓冲区将被锁定,并且失败,返回WSA_IO_PENDING,当数据来到时,将被直接复制到程序的缓冲区,绕过了socket的接收缓冲区


缓冲区模型(我猜想的)

Application Buffer

Socket Buffer

Tcp(Driver) Buffer


将SOCKET的 buffer 设为0 通常不能提供性能,因为只要有足够的overlapped send 和 receive 操作被投递,就可以避免额外的内存拷贝

禁用套接字的发送缓冲区通常比禁用接收缓冲区的影响小

因为:

Application Buffer将总是被锁定直到被传递到下层TCP处理,然而,如果接收缓冲区被设为0而没有足够的overalpped receive被调用

所有传来的数据将被缓冲在TCP层的Buffer,TCP Driver将缓存最多 receive window size -- 17K 的数据,这是极限,

通常 缓冲区要小得多,这些TCP缓冲区被分配在non-paged pool中,如果连接太多,这些non-paged pool 将被耗尽


只有几个特定情况不设定socket receive buffer才会降低性能:服务器有大量连接,而客户端只偶尔发送数据。


资源管理:

每一个overlapped send 或者 recive 操作的buffer都会被锁定,即it cannot be paged out of physical memory

可被系统锁定的内存是有限的,When this limit is reached, overlapped operations will fail with theWSAENOBUFS error

如果一个服务器要处理巨量的并发连接,服务器可以给每个连接投递长度为0的receive操作,通过这种方法

将没有内存被锁定,the per-socket receive buffer should be left intact because once the zero-byte receive operation completes, the server can simply perform a non-blocking receive to retrieve all the data buffered in the socket's receive buffer. There is no more data pending when the non-blocking receive fails with WSAEWOULDBLOCK

这种设计适用于要求最大化并发数,但可牺牲吞吐量的情况。

a non-blocking receive is performed once the zero-byte receive completes to retrieve the buffered data. If the server knows that clients send data in bursts, then once the zero-byte receive completes, it may post one or more overlapped receives in case the client sends a substantial amount of data (greater than the per-socket receive buffer that is 8 KB by default).


一个连接的套接字消耗2KB的 non-paged pool

accpet返回的套接字消耗1.5KB的non-paged pool

每一个overlapped操作消耗大约500bytes的non-paged pool


服务器策略:

服务器带该可以分为2种:

1.High Throughput:

主要考虑在少量连接上传输数据,当然这个“少量”是相对服务器可接受的连接而言的。

2.高并发

主要考虑多并发而不发送大量数据的连接


你可能感兴趣的:(socket,网络,服务器,performance,Signal)