1.小端法(Little-Endian)就是低位字节排放在内存的低地址端即该值的起始地址,高位字节排放在内存的高地址端。
2.大端法(Big-Endian)就是高位字节排放在内存的低地址端即该值的起始地址,低位字节排放在内存的高地址端。
举个简单的例子,对于整形0x12345678。它在大端法和小端法的系统内中,分别如图1所示的方式存放。
网络字节序
网络字节序说是大端字节序。
TCP中API调用过程
Server端:
WSAStartup() -> socket() -> bind() -> listen() ->accept() -> recv() ->closesocket() -> WSACleanup()
Client端:
WSAStartup() -> socket() ->connect() -> send() -> closesocket() -> WSACleanup()
UDP中API调用:
Server端:
WSAStartup() -> socket() -> bind() -> recvfrom() -> closesocket() ->WSACleanup()
Client端:
WSAStartup() -> socket() -> sendto() -> closesocket() -> WSACleanup()
下面是
① 阻塞模式
② 非阻塞模式
③ Select模型
④ WSAAsyncSelect模型
⑤ WSAEventSelect模型
⑥ 重叠I/O模型
⑦ 完成端口模型(IOCP)
1阻塞模式
I/O操作完成前,执行的操作函数将一直等待而不会立即返回,该函数所在的线程会阻塞在这里。
非阻塞模式下,套接字函数会立即返回,而不管I/O是否完成,该函数所在线程将继续执行。
缺点:处理大量套接字时,无从下手。
2非阻塞模式
通过ioctlsocket()函数可以将套接字设置为非阻塞。
重复调用recv()直到收到数据为止,浪费系统资源。
3Select选择模型
可以同时对多个建立起来的套接字进行管理,通过判断可读可写来进行处理。
Select函数调用时阻塞的。每一次数据的发送和接收都要经过两次windows socket函数调用。
3WSAAsyncSelect模型
异步I/O,非阻塞模型,接收以windows消息为基础的网络事件。
因为消息驱动,必须创建窗口。
4.WSAEventSelect模型
接收以事件为基础的网络事件通知。
每个WSAEventSelect模型最多只能管理64个套接字,当多于64个套接字的时候,就需要额外创建线程。
5重叠I/O模型
系统向应用程序发送通知的形式有两种:事件通知和完成例程。
与前三个比较区别:
套接字重叠I/O的事件通知方法要求将事件对象与WSAOVERLAPPED结构关联。当I/O操作完成后,该事件对象从“未传信”状态变为“已传信”状态。在应用程序中先调用WSAWaitForMultipleEvents()函数等待该事件的发生,然后调用WSAGetOverlappedResult()函数判断I/O操作完成情况。
完成例程:当发起重叠操作时,将该函数传递给发起操作的函数。完成例程是一个回调函数。(不太懂,回头慢慢看)
6完成端口模型(可处理成百上千个套接字)
服务器的线程模型
串行和并发,串行就是一次只处理一个,并发则同时处理多个。
显然要选择并发,但要注意对于多用户创建线程要适当,否则大部分时间会浪费在线程上下文切换上面,同时要避免不断地创建和销毁线程。
解决就是为完成端口指定并发线程的数量,在初始化套接字时创建一定属相的服务线程,即所谓的线程池。
当系统完成I/O操作后,向服务器完成端口发送I/O completion packet,等待I/O操作的线程将按照后进先出(LIFO)方式被唤醒,主要是可以避免上下文切换。
通常服务线程数量为CPU数量的2倍。
之后会主要研究完成端口。