IOCP模型与网络编程

IOCP模型与网络编程

一。前言:
       
在老师分配任务(“尝试利用IOCP模型写出服务端和客户端的代码”)给我时,脑子一片空白,并不知道什么是IOCP模型,会不会是像软件设计模式里面的工厂模式,装饰模式之类的那些呢?嘿嘿,不过好像是一个挺好玩的东西,挺好奇是什么东西来的,又是一个新知识啦~于是,开始去寻找一大堆的资料,为这个了解做准备,只是呢,有时还是想去找一本书去系统地学习一下,毕竟网络的资料还是有点零散。话说,本人学习这个模型的基础是,写过一个简单的Socket服务器及客户端程序,外加一个简单的Socket单服务器对多客户端程序,懂一点点的操作系统原理的知识。于是,本着一个学习与应用的态度开始探究这个IOCP是个什么东西。

二。提出相关问题:
       1. 
IOCP模型是什么?
       2. 
IOCP模型是用来解决什么问题的?它为什么存在?
       3. 
使用IOCP模型需要用到哪些知识?
       4. 
如何使用IOCP模型与Socket网络编程结合起来?
       5. 
学会了这个模型以后与我之前写过的简单的socket程序主要有哪些不同点?

三。部分问题探究及解决:(绝大多数是个人理解,再加上个人是菜鸟,如果有什么不对的地方,欢迎指正)
       1. 
什么是IOCP?什么是IOCP模型?IOCP模型有什么作用?
              1)
IOCP(I/O Completion
Port),常称I/O完成端口。
              2)
IOCP模型属于一种通讯模型,适用于(能控制并发执行的)高负载服务器的一个技术。
              3)
通俗一点说,就是用于高效处理很多很多的客户端进行数据交换的一个模型。
              4)
或者可以说,就是能异步I/O操作的模型。
              5)
只是了解到这些会让人很糊涂,因为还是不知道它究意具体是个什么东东呢?

下面我想给大家看三个图:
第一个是IOCP的内部工作队列图。(整合于《IOCP本质论》文章,在英文的基础上加上中文对照)
 

第二个是程序实现IOCP模型的基本步骤。(整合于《深入解释IOCP》,加个人观点、理解、翻译)
 
?

第三个是使用了IOCP模型及没使用IOCP模型的程序流程图。(个人理解绘制)
 

2. 
IOCP的存在理由(IOCP的优点)及技术相关有哪些?
       
之前说过,很通俗地理解可以理解成是用于高效处理很多很多的客户端进行数据交换的一个模型,那么,它具体的优点有些什么呢?它到底用到了哪些技术了呢?在Windows环境下又如何去使用这些技术来编程呢?它主要使用上哪些API函数呢?呃~看来我真是一个问题多多的人,跟前面提出的相关问题变种延伸了不少的问题,好吧,下面一个个来解决。

1) 使用IOCP模型编程的优点
       ①
帮助维持重复使用的内存池。(与重叠I/O技术有关)
       ②
去除删除线程创建/终结负担。
       ③
利于管理,分配线程,控制并发,最小化的线程上下文切换。
       ④
优化线程调度,提高CPU和内存缓冲的命中率。

2) 使用IOCP模型编程汲及到的知识点(无先后顺序)
       ①
同步与异步
       ②
阻塞与非阻塞
       ③
重叠I/O技术
       ④
多线程
       ⑤ 栈、队列这两种基本的数据结构

3) 需要使用上的API函数
  ①
与SOCKET相关
       1、链接套接字动态链接库:int
WSAStartup(...);
       2、创建套接字库:       
SOCKET
socket(...);
       3、绑字套接字:         
int bind(...);
       4、套接字设为监听状态: int
listen(...);
       5、接收套接字:         
SOCKET
accept(...);
       6、向指定套接字发送信息:int
send(...);
       7、从指定套接字接收信息:int
recv(...);

② 与线程相关
       1、创建线程:HANDLE
CreateThread(...);


重叠I/O技术相关
       1、向套接字发送数据:   
int
WSASend(...);
       2、向套接字发送数据包: 
int
WSASendFrom(...);
       3、从套接字接收数据:   
int
WSARecv(...);
       4、从套接字接收数据包: 
int WSARecvFrom(...);

④ IOCP相关
       1、创建完成端口: HANDLE
WINAPI
CreateIoCompletionPort(...);
       2、关联完成端口:
HANDLE WINAPI
CreateIoCompletionPort(...);
       3、获取队列完成状态:
BOOL WINAPI
GetQueuedCompletionStatus(...);
       4、投递一个队列完成状态:BOOL
WINAPI PostQueuedCompletionStatus(...);

四。完整的简单的IOCP服务器与客户端代码实例:

[cpp] view plaincopyprint?

  1. // IOCP_TCPIP_Socket_Server.cpp
  2. #include <WinSock2.h>

  3. #include <Windows.h>

  4. #include <vector>

  5. #include <iostream>
  6. using namespace std;
  7. #pragma comment(lib, "Ws2_32.lib")      // Socket编程需用的动态链接库

  8. #pragma comment(lib, "Kernel32.lib")    // IOCP需要用到的动态链接库
  9. /**

  10. * 结构体名称:PER_IO_DATA

  11. * 结构体功能:重叠I/O需要用到的结构体,临时记录IO数据

  12. **/

  13. const int DataBuffSize  = 2 * 1024;

  14. typedef struct

  15. {

  16. OVERLAPPED overlapped;

  17. WSABUF databuff;

  18. char buffer[ DataBuffSize ];

  19. int BufferLen;

  20. int operationType;

  21. }PER_IO_OPERATEION_DATA, *LPPER_IO_OPERATION_DATA, *LPPER_IO_DATA, PER_IO_DATA;
  22. /**

  23. * 结构体名称:PER_HANDLE_DATA

  24. * 结构体存储:记录单个套接字的数据,包括了套接字的变量及套接字的对应的客户端的地址。

  25. * 结构体作用:当服务器连接上客户端时,信息存储到该结构体中,知道客户端的地址以便于回访。

  26. **/

  27. typedef struct

  28. {

  29. SOCKET socket;

  30. SOCKADDR_STORAGE ClientAddr;

  31. }PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
  32. // 定义全局变量

  33. const int DefaultPort = 6000;

  34. vector < PER_HANDLE_DATA* > clientGroup;      // 记录客户端的向量组
  35. HANDLE hMutex = CreateMutex(NULL, FALSE, NULL);

  36. DWORD WINAPI ServerWorkThread(LPVOID CompletionPortID);

  37. DWORD WINAPI ServerSendThread(LPVOID IpParam);
  38. // 开始主函数

  39. int main()

  40. {

  41. // 加载socket动态链接库

  42. WORD wVersionRequested = MAKEWORD(2, 2); // 请求2.2版本的WinSock库

  43. WSADATA wsaData;    // 接收Windows Socket的结构信息

  44. DWORD err = WSAStartup(wVersionRequested, &wsaData);
  45. if (0 != err){  // 检查套接字库是否申请成功

  46. cerr << "Request Windows Socket Library Error!\n";

  47. system("pause");

  48. return -1;

  49. }

  50. if(LOBYTE(wsaData.wVersion) != 2 || HIBYTE(wsaData.wVersion) != 2){// 检查是否申请了所需版本的套接字库

  51. WSACleanup();

  52. cerr << "Request Windows Socket Version 2.2 Error!\n";

  53. system("pause");

  54. return -1;

  55. }
  56. // 创建IOCP的内核对象

  57. /**

  58. * 需要用到的函数的原型:

  59. * HANDLE WINAPI CreateIoCompletionPort(

  60. *    __in   HANDLE FileHandle,     // 已经打开的文件句柄或者空句柄,一般是客户端的句柄

  61. *    __in   HANDLE ExistingCompletionPort, // 已经存在的IOCP句柄

  62. *    __in   ULONG_PTR CompletionKey,   // 完成键,包含了指定I/O完成包的指定文件

  63. *    __in   DWORD NumberOfConcurrentThreads // 真正并发同时执行最大线程数,一般推介是CPU核心数*2

  64. * );

  65. **/

  66. HANDLE completionPort = CreateIoCompletionPort( INVALID_HANDLE_VALUE, NULL, 0, 0);

  67. if (NULL == completionPort){    // 创建IO内核对象失败

  68. cerr << "CreateIoCompletionPort failed. Error:" << GetLastError() << endl;

  69. system("pause");

  70. return -1;

  71. }
  72. // 创建IOCP线程--线程里面创建线程池
  73. // 确定处理器的核心数量

  74. SYSTEM_INFO mySysInfo;

  75. GetSystemInfo(&mySysInfo);
  76. // 基于处理器的核心数量创建线程

  77. for(DWORD i = 0; i < (mySysInfo.dwNumberOfProcessors * 2); ++i){

  78. // 创建服务器工作器线程,并将完成端口传递到该线程

  79. HANDLE ThreadHandle = CreateThread(NULL, 0, ServerWorkThread, completionPort, 0, NULL);

  80. if(NULL == ThreadHandle){

  81. cerr << "Create Thread Handle failed. Error:" << GetLastError() << endl;

  82. system("pause");

  83. return -1;

  84. }

  85. CloseHandle(ThreadHandle);

  86. }
  87. // 建立流式套接字

  88. SOCKET srvSocket = socket(AF_INET, SOCK_STREAM, 0);
  89. // 绑定SOCKET到本机

  90. SOCKADDR_IN srvAddr;

  91. srvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);

  92. srvAddr.sin_family = AF_INET;

  93. srvAddr.sin_port = htons(DefaultPort);

  94. int bindResult = bind(srvSocket, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR));

  95. if(SOCKET_ERROR == bindResult){

  96. cerr << "Bind failed. Error:" << GetLastError() << endl;

  97. system("pause");

  98. return -1;

  99. }
  100. // 将SOCKET设置为监听模式

  101. int listenResult = listen(srvSocket, 10);

  102. if(SOCKET_ERROR == listenResult){

  103. cerr << "Listen failed. Error: " << GetLastError() << endl;

  104. system("pause");

  105. return -1;

  106. }
  107. // 开始处理IO数据

  108. cout << "本服务器已准备就绪,正在等待客户端的接入...\n";
  109. // 创建用于发送数据的线程

  110. HANDLE sendThread = CreateThread(NULL, 0, ServerSendThread, 0, 0, NULL);
  111. while(true){

  112. PER_HANDLE_DATA * PerHandleData = NULL;

  113. SOCKADDR_IN saRemote;

  114. int RemoteLen;

  115. SOCKET acceptSocket;
  116. // 接收连接,并分配完成端,这儿可以用AcceptEx()

  117. RemoteLen = sizeof(saRemote);

  118. acceptSocket = accept(srvSocket, (SOCKADDR*)&saRemote, &RemoteLen);

  119. if(SOCKET_ERROR == acceptSocket){   // 接收客户端失败

  120. cerr << "Accept Socket Error: " << GetLastError() << endl;

  121. system("pause");

  122. return -1;

  123. }
  124. // 创建用来和套接字关联的单句柄数据信息结构

  125. PerHandleData = (LPPER_HANDLE_DATA)GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));  // 在堆中为这个PerHandleData申请指定大小的内存

  126. PerHandleData -> socket = acceptSocket;

  127. memcpy (&PerHandleData -> ClientAddr, &saRemote, RemoteLen);

  128. clientGroup.push_back(PerHandleData);       // 将单个客户端数据指针放到客户端组中
  129. // 将接受套接字和完成端口关联

  130. CreateIoCompletionPort((HANDLE)(PerHandleData -> socket), completionPort, (DWORD)PerHandleData, 0);
  131. // 开始在接受套接字上处理I/O使用重叠I/O机制

  132. // 在新建的套接字上投递一个或多个异步

  133. // WSARecv或WSASend请求,这些I/O请求完成后,工作者线程会为I/O请求提供服务

  134. // 单I/O操作数据(I/O重叠)

  135. LPPER_IO_OPERATION_DATA PerIoData = NULL;

  136. PerIoData = (LPPER_IO_OPERATION_DATA)GlobalAlloc(GPTR, sizeof(PER_IO_OPERATEION_DATA));

  137. ZeroMemory(&(PerIoData -> overlapped), sizeof(OVERLAPPED));

  138. PerIoData->databuff.len = 1024;

  139. PerIoData->databuff.buf = PerIoData->buffer;

  140. PerIoData->operationType = 0;    // read
  141. DWORD RecvBytes;

  142. DWORD Flags = 0;

  143. WSARecv(PerHandleData->socket, &(PerIoData->databuff), 1, &RecvBytes, &Flags, &(PerIoData->overlapped), NULL);

  144. }
  145. system("pause");

  146. return 0;

  147. }
  148. // 开始服务工作线程函数

  149. DWORD WINAPI ServerWorkThread(LPVOID IpParam)

  150. {

  151. HANDLE CompletionPort = (HANDLE)IpParam;

  152. DWORD BytesTransferred;

  153. LPOVERLAPPED IpOverlapped;

  154. LPPER_HANDLE_DATA PerHandleData = NULL;

  155. LPPER_IO_DATA PerIoData = NULL;

  156. DWORD RecvBytes;

  157. DWORD Flags = 0;

  158. BOOL bRet = false;
  159. while(true){

  160. bRet = GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (PULONG_PTR)&PerHandleData, (LPOVERLAPPED*)&IpOverlapped, INFINITE);

  161. if(bRet == 0){

  162. cerr << "GetQueuedCompletionStatus Error: " << GetLastError() << endl;

  163. return -1;

  164. }

  165. PerIoData = (LPPER_IO_DATA)CONTAINING_RECORD(IpOverlapped, PER_IO_DATA, overlapped);
  166. // 检查在套接字上是否有错误发生

  167. if(0 == BytesTransferred){

  168. closesocket(PerHandleData->socket);

  169. GlobalFree(PerHandleData);

  170. GlobalFree(PerIoData);

  171. continue;

  172. }
  173. // 开始数据处理,接收来自客户端的数据

  174. WaitForSingleObject(hMutex,INFINITE);

  175. cout << "A Client says: " << PerIoData->databuff.buf << endl;

  176. ReleaseMutex(hMutex);
  177. // 为下一个重叠调用建立单I/O操作数据

  178. ZeroMemory(&(PerIoData->overlapped), sizeof(OVERLAPPED)); // 清空内存

  179. PerIoData->databuff.len = 1024;

  180. PerIoData->databuff.buf = PerIoData->buffer;

  181. PerIoData->operationType = 0;    // read

  182. WSARecv(PerHandleData->socket, &(PerIoData->databuff), 1, &RecvBytes, &Flags, &(PerIoData->overlapped), NULL);

  183. }
  184. return 0;

  185. }
  186. // 发送信息的线程执行函数

  187. DWORD WINAPI ServerSendThread(LPVOID IpParam)

  188. {

  189. while(1){

  190. char talk[200];

  191. gets(talk);

  192. int len;

  193. for (len = 0; talk[len] != ‘\0‘; ++len){

  194. // 找出这个字符组的长度

  195. }

  196. talk[len] = ‘\n‘;

  197. talk[++len] = ‘\0‘;

  198. printf("I Say:");

  199. cout << talk;

  200. WaitForSingleObject(hMutex,INFINITE);

  201. for(int i = 0; i < clientGroup.size(); ++i){

  202. send(clientGroup[i]->socket, talk, 200, 0);  // 发送信息

  203. }

  204. ReleaseMutex(hMutex);

  205. }

  206. return 0;

  207. }

[cpp] view plaincopyprint?

  1. // IOCP_TCPIP_Socket_Client.cpp
  2. #include <iostream>

  3. #include <cstdio>

  4. #include <string>

  5. #include <cstring>

  6. #include <winsock2.h>

  7. #include <Windows.h>
  8. using namespace std;
  9. #pragma comment(lib, "Ws2_32.lib")      // Socket编程需用的动态链接库
  10. SOCKET sockClient;      // 连接成功后的套接字

  11. HANDLE bufferMutex;     // 令其能互斥成功正常通信的信号量句柄

  12. const int DefaultPort = 6000;
  13. int main()

  14. {

  15. // 加载socket动态链接库(dll)

  16. WORD wVersionRequested;

  17. WSADATA wsaData;    // 这结构是用于接收Wjndows Socket的结构信息的

  18. wVersionRequested = MAKEWORD( 2, 2 );   // 请求2.2版本的WinSock库

  19. int err = WSAStartup( wVersionRequested, &wsaData );

  20. if ( err != 0 ) {   // 返回值为零的时候是表示成功申请WSAStartup

  21. return -1;

  22. }

  23. if ( LOBYTE( wsaData.wVersion ) != 2 || HIBYTE( wsaData.wVersion ) != 2 ) { // 检查版本号是否正确

  24. WSACleanup( );

  25. return -1;

  26. }
  27. // 创建socket操作,建立流式套接字,返回套接字号sockClient

  28. sockClient = socket(AF_INET, SOCK_STREAM, 0);

  29. if(sockClient == INVALID_SOCKET) {

  30. printf("Error at socket():%ld\n", WSAGetLastError());

  31. WSACleanup();

  32. return -1;

  33. }
  34. // 将套接字sockClient与远程主机相连

  35. // int connect( SOCKET s,  const struct sockaddr* name,  int namelen);

  36. // 第一个参数:需要进行连接操作的套接字

  37. // 第二个参数:设定所需要连接的地址信息

  38. // 第三个参数:地址的长度

  39. SOCKADDR_IN addrSrv;

  40. addrSrv.sin_addr.S_un.S_addr = inet_addr("127.0.0.1");      // 本地回路地址是127.0.0.1;

  41. addrSrv.sin_family = AF_INET;

  42. addrSrv.sin_port = htons(DefaultPort);

  43. while(SOCKET_ERROR == connect(sockClient, (SOCKADDR*)&addrSrv, sizeof(SOCKADDR))){

  44. // 如果还没连接上服务器则要求重连

  45. cout << "服务器连接失败,是否重新连接?(Y/N):";

  46. char choice;

  47. while(cin >> choice && (!((choice != ‘Y‘ && choice == ‘N‘) || (choice == ‘Y‘ && choice != ‘N‘)))){

  48. cout << "输入错误,请重新输入:";

  49. cin.sync();

  50. cin.clear();

  51. }

  52. if (choice == ‘Y‘){

  53. continue;

  54. }

  55. else{

  56. cout << "退出系统中...";

  57. system("pause");

  58. return 0;

  59. }

  60. }

  61. cin.sync();

  62. cout << "本客户端已准备就绪,用户可直接输入文字向服务器反馈信息。\n";
  63. send(sockClient, "\nAttention: A Client has enter...\n", 200, 0);
  64. bufferMutex = CreateSemaphore(NULL, 1, 1, NULL);
  65. DWORD WINAPI SendMessageThread(LPVOID IpParameter);

  66. DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter);
  67. HANDLE sendThread = CreateThread(NULL, 0, SendMessageThread, NULL, 0, NULL);

  68. HANDLE receiveThread = CreateThread(NULL, 0, ReceiveMessageThread, NULL, 0, NULL);
  69. WaitForSingleObject(sendThread, INFINITE);  // 等待线程结束

  70. closesocket(sockClient);

  71. CloseHandle(sendThread);

  72. CloseHandle(receiveThread);

  73. CloseHandle(bufferMutex);

  74. WSACleanup();   // 终止对套接字库的使用
  75. printf("End linking...\n");

  76. printf("\n");

  77. system("pause");

  78. return 0;

  79. }
  80. DWORD WINAPI SendMessageThread(LPVOID IpParameter)

  81. {

  82. while(1){

  83. string talk;

  84. getline(cin, talk);

  85. WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)

  86. if("quit" == talk){

  87. talk.push_back(‘\0‘);

  88. send(sockClient, talk.c_str(), 200, 0);

  89. break;

  90. }

  91. else{

  92. talk.append("\n");

  93. }

  94. printf("\nI Say:(\"quit\"to exit):");

  95. cout << talk;

  96. send(sockClient, talk.c_str(), 200, 0); // 发送信息

  97. ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)

  98. }

  99. return 0;

  100. }
  101. DWORD WINAPI ReceiveMessageThread(LPVOID IpParameter)

  102. {

  103. while(1){

  104. char recvBuf[300];

  105. recv(sockClient, recvBuf, 200, 0);

  106. WaitForSingleObject(bufferMutex, INFINITE);     // P(资源未被占用)
  107. printf("%s Says: %s", "Server", recvBuf);       // 接收信息
  108. ReleaseSemaphore(bufferMutex, 1, NULL);     // V(资源占用完毕)

  109. }

  110. return 0;

  111. }

五。本次学习资料
       几翻周折,终于写出一个比较简单的IOCP模型的服务器与客户端啦,并且也大概了解这个模型的思路啦~没有买书的娃,伤不起啊,只能从网上搜罗资料,幸好有这些文章在,最后为下列这些文章的作者说声谢谢~

from:http://blog.csdn.net/neicole/article/details/7549497

IOCP模型与网络编程,码迷,mamicode.com

时间: 2024-09-30 15:39:27

IOCP模型与网络编程的相关文章

IOCP模型与网络编

一.前言:        在老师分配任务(“尝试利用IOCP模型写出服务端和客户端的代码”)给我时,脑子一片空白,并不知道什么是IOCP模型,会不会是像软件设计模式里面的工厂模式,装饰模式之类的那些呢?嘿嘿,不过好像是一个挺好玩的东西,挺好奇是什么东西来的,又是一个新知识啦~于是,开始去寻找一大堆的资料,为这个了解做准备,只是呢,有时还是想去找一本书去系统地学习一下,毕竟网络的资料还是有点零散.话说,本人学习这个模型的基础是,写过一个简单的Socket服务器及客户端程序,外加一个简单的Socke

网络编程模型及网络编程三要素

网络模型 计算机网络之间以何种规则进行通信,就是网络模型研究问题. 网络模型一般是指 OSI(Open SystemInterconnection开放系统互连)参考模型 TCP/IP参考模型 网络模型7层概述: 1.物理层:主要定义物理设备标准,如网线的接口类型.光纤的接口类型.各种传输介质的传输速率等.它的主要作用是传输比特流(就是由1.0转化为电流强弱来进行传输,到达目的地后在转化为1.0,也就是我们常说的数模转换与模数转换).这一层的数据叫做比特. 2. 数据链路层:主要将从物理层接收的数

Window下高性能IOCP模型队列多线程下应用

IOCP,先从概念上认识一下.IOCP全称I/O Completion Port,中文译为I/O完成端口.是Windows平台最高效的I/O模块,现在IIS服务器,就采用IOCP模型.IOCP是一个异步I/O的API,它可以高效地将I/O事件通知给应用程序.与使用select()或是其它异步方法不同的是,现在很多书,文字都直接将IOCP模块和网络编程关联起来,好像IOCP就是和网络打交道的.典型的IOCP模型的使用,是 将一个套接字(socket)与一个完成端口关联了起来,当一个网络事件发生的时

java网络编程笔记

1:网络编程(理解) (1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享 (2)网络编程模型 (3)网络编程的三要素 A:IP地址 a:点分十进制 b:IP地址的组成 c:IP地址的分类 d:dos命令 e:InetAddress B:端口 是应用程序的标识.范围:0-65535.其中0-1024不建议使用. C:协议 UDP:数据打包,有限制,不连接,效率高,不可靠 TCP:建立数据通道,无限制,效率低,可靠 (3)Socket机制 A:通信两端都应该有Socket对象 B:所

重踏学习Java路上_Day26(网络编程)

1:网络编程(理解)    (1)网络编程:用Java语言实现计算机间数据的信息传递和资源共享    (2)网络编程模型    (3)网络编程的三要素        A:IP地址            a:点分十进制            b:IP地址的组成            c:IP地址的分类            d:dos命令            e:InetAddress        B:端口            是应用程序的标识.范围:0-65535.其中0-1024不建议使

基于ASIO的协程与网络编程

协程 协程,即协作式程序,其思想是,一系列互相依赖的协程间依次使用CPU,每次只有一个协程工作,而其他协程处于休眠状态.协程可以在运行期间的某个点上暂停执行,并在恢复运行时从暂停的点上继续执行. 协程已经被证明是一种非常有用的程序组件,不仅被python.lua.ruby等脚本语言广泛采用,而且被新一代面向多核的编程语言如golang rust-lang等采用作为并发的基本单位. 协程可以被认为是一种用户空间线程,与传统的线程相比,有2个主要的优点: 与线程不同,协程是自己主动让出CPU,并交付

Linux网络编程-----TCP程序设计

基于TCP-服务器 1.创建一个socket, 2.绑定IP地址.端口等信息到socket上,用函数bind() 3.设置允许的最大连接数,用函数listen(). 4.等待来自客户端的连接请求,用accept() 5.收发数据,用函数send()和recv(),或者read()和write() 6.关闭网络连接 基于TCP-客户端 1.socket创建套接字 2.设置要连接服务器的IP地址和端口等属性 3.连接服务器,用函数connect() 4.收发数据,用函数send()和recv(),或

第7章 网络编程考察点

网络协议TCP/UDP/HTTP 常考题 浏览器输入一个url中间经历的过程 中间涉及到了哪些过程 包含哪些网络协议 每个协议都干了什么? DNS查询->TCP握手->HTTP请求->反向代理Nginx->uwsgi/gunicom->web app响应->TCP挥手 TCP三次握手过程 TCP三次握手, 状态转换.用wireshark抓包更直观 TCP四次挥手过程 TCP四次挥手,状态装换 client state C S server state TCP/UDP的区

winsock编程IOCP模型实现代码

winsock编程IOCP模型实现代码 话不多说,上代码.借鉴<windows核心编程>部分源码和CSDN小猪部分代码. stdafx.h依赖头文件: 1 #include <iostream> 2 #include <WinSock2.h> 3 #include <MSWSock.h> 4 #include <vector> 5 #include "Singleton.h" 6 #include "IOCPWrap