1、理论上一台服务器最多能接受多少个连接?是65535吗?
理论上要大于65535,若计算机配置及带宽等条件无限,可以实现无限连接:
背景: A、监听端口和通信端口是同一个:socket编程时服务端会指定一个端口进行监听,客户端连接进来后返回一个新的socket,这个socket是客户端连接
进来的socket,用来区别不同的客户端,因此不管有多少客户端连接进来,若一开始程序就只使用了一个监听端口,则不会占用其它新的端口
B、通常所说的65535限制是针对客户端而言。一台电脑打开n个客户端与服务器连接,则客户端消耗n个端口,而n<=65535
1)、虽然windows默认有65535个端口(XP,其它系统不知),但是可以通过更改系统配置文件打开更多端口
2)、从socket编程可知,连接进来的客户端是ip+port形式确定的,一个ip在默认情况下最多有65535个端口,而ip不定,所以结果肯定大于65535
3)、虽然理论上可以支持超过65536的连接,但实际中要实现这样的服务器,并且还要求是长连接的话,不管是对服务器配置,服务器带宽,还是对程序员都是一个考验
2、使用bind与不使用bind的区别
1)、当使用TCP协议时,服务端必须使用bind,这样才能实时监听随时有可能连接进来的客户端,而客户端则没必要使用bind(这时,客户端随机分配)
2)、当使用UDP协议时,若是C/S模式,则服务端客户端有无bind都没太大影响,如果是对等通信(P2P等)则两端都需要bind
3、iocp
A、使用CreateIoCompletionPort、GetQueuedCompletionStatus、recv/recvFrom、send/sendTo组成的完成端口
B、使用CreateIoCompletionPort、GetQueuedCompletionStatus、WSARecv/WSARecvFrom、send/sendTo组成的完成端口
C、使用CreateIoCompletionPort、GetQueuedCompletionStatus、WSARecv/WSARecvFrom、WSASend(单发)组成的完成端口
D、使用CreateIoCompletionPort、GetQueuedCompletionStatus、WSARecv/WSARecvFrom、WSASend(群发)、PostQueuedCompletionStatus组成的完成端口
1)、使用WSASend发送消息时(已注释):
int
WSAAPI
WSASend(
__in SOCKET s,
__in_ecount(dwBufferCount) LPWSABUF lpBuffers, //可使用临时变量,而WSARecv的此参数不能,只能使用全局变量
__in DWORD dwBufferCount,
__out_opt LPDWORD lpNumberOfBytesSent,
__in DWORD dwFlags,
__inout_opt LPWSAOVERLAPPED lpOverlapped, //只能使用全局变量?!WSARecv一样?!(暂未测试)
__in_opt LPWSAOVERLAPPED_COMPLETION_ROUTINE lpCompletionRoutine
);
使用WSASend还需要注意一点的是每WSASend一次lpOverlapped参数都要重新再堆分配,这样可以避免一个WSASend还没完成,下一个WSASend破坏了Overlapped,最终导致数据发送出现问题。当然如果你能百分百保证每次WSASend时前一次使用的Overlapped已经结束,则可以只使用一个Overlapped结构
或者1个SOCKET对应一个
2)、WSARecv接收时
a、当WSABUF的len变量赋值为buffer长度时,GetQueuedCompletionStatus相应后,可直接依据CONTAINING_RECORD宏获取到接收到的数据,即 WSABUF.buf里的数据
b、当WSABUF的len变量赋值为0时,GetQueuedCompletionStatus相应后,WSABUF.buf还是为空?!还需要用recv函数接收数据?!用于接收的buffer
为WSABUF.buf指向的buffer