永发信息网

为一个iocp模型的代码加注释

答案:1  悬赏:60  手机版
解决时间 2021-05-11 11:39

要详细:

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>

#pragma comment(lib,"ws2_32.lib")

#define LISTEN_PORT   8080
#define BUFFER_SIZE   1024

typedef struct _PER_HANDLE_DATA

{
 
 SOCKET s;
 sockaddr_in addr;
} PER_HANDLE_DATA, *PPER_HANDLE_DATA;

typedef struct _PER_IO_DATA

{
 OVERLAPPED ol;

 char buf[BUFFER_SIZE];

 int nOperationType;

 #define OP_READ   1
 #define OP_WRITE  2
 #define OP_ACCEPT  3
 
} PER_IO_DATA, *PPER_IO_DATA;

DWORD WINAPI ServerThread(LPVOID lpParam)
{
 DWORD dwTrans   = 0;
 DWORD dwFlags   = 0;
 HANDLE hCompletion  = (HANDLE)lpParam;

 PPER_IO_DATA  pPerIo  = NULL;
 PPER_HANDLE_DATA pPerHandle = NULL;

 while (true)
 {
  BOOL bOK;
  
  bOK = ::GetQueuedCompletionStatus(hCompletion, &dwTrans, (LPDWORD)pPerHandle, (LPOVERLAPPED*)&pPerIo, WSA_INFINITE);

  if (!bOK)
  {
//   ::closesocket(pPerHandle->s);
   ::GlobalFree(pPerHandle);
   ::GlobalFree(pPerIo);

   continue;
  }

  if (dwTrans == 0 && (pPerIo->nOperationType == OP_READ  || pPerIo->nOperationType == OP_WRITE))
  {
   ::closesocket(pPerHandle->s);
   ::GlobalFree(pPerHandle);
   ::GlobalFree(pPerIo);
  }

  switch (pPerIo->nOperationType)
  {
   case OP_READ:
    {
     pPerIo->buf[dwTrans] = '\0';
     printf(pPerIo->buf);

     WSABUF WSABuf;
     WSABuf.buf = pPerIo->buf;
     WSABuf.len = BUFFER_SIZE;

     pPerIo->nOperationType = OP_READ;

     ::WSARecv(pPerHandle->s, &WSABuf, 1, &dwTrans, &dwFlags, &pPerIo->ol, NULL);

     break;
    }

   case OP_WRITE:
     break;

   case OP_ACCEPT:
     break;
  }
 }

 return 0;
}

int main()
{
 WSADATA   WSAData;
 WORD   wVersion = MAKEWORd(2, 2);

 SOCKET   sListen  = 0;
 SOCKET   sAccept  = 0;

 HANDLE   hCompletion = 0;

 hCompletion = ::CreateIoCompletionPort(INVALID_HANDLE_VALUE, 0, 0, 0);
 ::CreateThread(NULL, 0, ServerThread, (LPVOID)hCompletion, 0, 0);

 if (::WSAStartup(wVersion, &WSAData) != 0)
 {
  ::WSACleanup();

  return -1;
 }

 sListen = ::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 if (sListen == INVALID_SOCKET)
 {
  ::closesocket(sListen);

  return -2;
 }

 sockaddr_in  TCP;

 TCP.sin_family    = AF_INET;
 TCP.sin_port    = htons(LISTEN_PORT);
 TCP.sin_addr.S_un.S_addr = INADDR_ANY;

 if (::bind(sListen, (sockaddr*)&TCP, sizeof(TCP)) == SOCKET_ERROR)
 {
  ::closesocket(sListen);

  return -3;
 }

 if (::listen(sListen, 5) == SOCKET_ERROR)
 {
  ::closesocket(sListen);

  return -4;
 }

 while (true)
 {
  sockaddr_in  remote;

  int nLen = sizeof(remote);

  SOCKET sThread = ::accept(sListen, (sockaddr*)&remote, &nLen);

  PPER_HANDLE_DATA pPerHandle = (PPER_HANDLE_DATA)::GlobalAlloc(GPTR, sizeof(PER_HANDLE_DATA));

  pPerHandle->s = sThread;
  memcpy(&pPerHandle->addr, &remote, nLen);

  ::CreateIoCompletionPort((HANDLE)pPerHandle->s, hCompletion, (DWORD)pPerHandle, 0);

  PPER_IO_DATA pPerIo = (PPER_IO_DATA)::GlobalAlloc(GPTR, sizeof(PER_IO_DATA));
  pPerIo->nOperationType = OP_READ;

  WSABUF buf;

  buf.buf = pPerIo->buf;
  buf.len = BUFFER_SIZE;

  DWORD dwRecv = 0;
  DWORD dwFlags = 0;

  ::WSARecv(pPerHandle->s, &buf, 1, &dwRecv, &dwFlags, &pPerIo->ol, NULL);
 }

 return 0;
}

 

再问下,如何学习iocp模型?

最佳答案
软件很简单,世界很复杂!
IOCP完成端口模型 简明级代码
2010年01月11日 星期一 15:44
view plaincopy to clipboardprint?
unit Unit1;
interface
uses
WinSock2, Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, ExtCtrls;
type
//单IO数据结构
LPER_IO_OPERATION_DATA = ^TPER_IO_OPERATION_DATA;
TPER_IO_OPERATION_DATA = packed record
Overlapped: WSAOverlapped;
DataBuf: WSABuf;
Buff: array [0..10] of Char;
BytesSend: DWORD;
BytesRecv: DWORD;
end;
//单句柄数据结构
LPER_HANDLE_DATA = ^TPER_HANDLE_DATA;
TPER_HANDLE_DATA = packed record
Socket: TSocket;
end;
TListenThread = class(TThread)
private
protected
procedure Execute;override;
public
constructor Create;
end;
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
private

public

end;
var
Form1: TForm1;
ServerSocket: TSocket;
implementation

//工作者线程
function WorkThread(CompletionPortID: Pointer):DWORD; stdcall;
var
CompletionPort: THandle;
BytesTransferred: DWORD;
PerHandleData: LPER_HANDLE_DATA;
PerIOData: LPER_IO_OPERATION_DATA;
Flags: DWORD;
RecvBytes: DWORD;
begin
CompletionPort:= THandle(CompletionPortID);
while True do
begin
//获取完成端口上的队列的完成状态
GetQueuedCompletionStatus(CompletionPort, BytesTransferred, DWORd(PerHandleData),
POverlapped(PerIOData), INFINITE);
//判断是客户端发来的数据还是服务端发出的数据
if PerIOData.BytesRecv = 0 then
begin
PerIOData.BytesRecv:= BytesTransferred;
PerIOData.BytesSend:= 0;
end else
Per
我要举报
如以上问答信息为低俗、色情、不良、暴力、侵权、涉及违法等信息,可以点下面链接进行举报!
大家都在看
在什么时间灭虫会得永久A车?
种花园有啥好处
那种无线上网卡网络好还省钱,都是多少钱的?
能帮我用英文解释几个单词吗?
过年做什么生意好
短发,还是长发好点?
葡萄的好处?
求魔方高级教程解法。要面对面教。。。
我的中国梦诗词,求强军梦中国梦诗词朗诵稿 20
得不到的真的会是最好的麽?
榕筑花园二区在哪里啊,我有事要去这个地方
大家觉得诛仙2会怎样写?
怎么样 才可以全部 隐藏全部图标
用成了造比喻句越多越好
金钱真的是万能吗?
推荐资讯
请问友介绍个好的illustrator基础教程
母狗多久一次情?国庆节发过一次,之后要到什
曾经或现在是炫舞紫钻的看看
雅芳便宜补水东东要适合16岁敏感肌肤的谢谢谢
我脚扭了,冬天大概多久才能好!我用了云南白药
形容即将接近尾声的大学生活的句子或名言
nokia C6怎么用。
我家网速怎么这样了?
我的问问怎么突然之间变零级
为什么下雨不会砸死人,为什么雨滴砸下来却砸
急求1条学习的名言
我为什么只胖上身呀
正方形一边上任一点到这个正方形两条对角线的
阴历怎么看 ?