php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 636|回复: 0

socket iocp模型

[复制链接]

3138

主题

3148

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
1
威望
0
积分
7946
贡献
0
注册时间
2021-4-14
最后登录
2024-11-21
在线时间
763 小时
QQ
发表于 2022-5-28 16:45:55 | 显示全部楼层 |阅读模式
[mw_shl_code=cpp,true]#include "IOCPEchoServ_win.h"
#include <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <winsock2.h>
#include <windows.h>

#define BUF_SIZE 100
#define READ 3
#define WRITE 5

typedef struct //socket info
{
        SOCKET hClntSock;
        SOCKADDR_IN clntAdr;
}PER_HANDLE_DATA,*LPPER_HANDLE_DATA;

typedef struct //buffer info
{
        OVERLAPPED overlapped;
        WSABUF wsaBuf;
        char buffer[BUF_SIZE];
        int rwMode; //READ or WRITE
}PER_IO_DATA,*LPPER_IO_DATA;

//DWORD WINAPI EchoThreadMain(LPVOID CompletionPortIO);
unsigned __stdcall EchoThreadMain(LPVOID CompletionPortIO);

//int main(int argc, char* argv[])
int IOCPEchoServ_win(int argc, char* argv[])
{
        WSADATA wsaData;
        HANDLE hComPort;
        SYSTEM_INFO sysInfo;
        LPPER_IO_DATA ioInfo;
        LPPER_HANDLE_DATA handleInfo;
        SOCKET hServSock;
        SOCKADDR_IN servAdr;
        DWORD recvBytes, i, flags;

        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0)
        {
                exit(1);
        }

        hComPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE,NULL,0,0);
        GetSystemInfo(&sysInfo);

        for (i = 0; i < sysInfo.dwNumberOfProcessors; i++)
        {
                //_beginthreadex(NULL,0,EchoThreadMain,(LPVOID)hComPort,0,NULL);
                _beginthreadex(NULL, 0, EchoThreadMain, (LPVOID)hComPort, 0, NULL);
        }
               

        hServSock = WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
        memset(&servAdr,0,sizeof(servAdr));
        servAdr.sin_family = AF_INET;
        servAdr.sin_addr.s_addr = htonl(INADDR_ANY);
        servAdr.sin_port = htons(atoi("9000"));

        bind(hServSock, (SOCKADDR*)&servAdr, sizeof(servAdr));
        listen(hServSock,5);

        while (1)
        {
                SOCKET hClntSock;
                SOCKADDR_IN clntAdr;
                int addLen = sizeof(clntAdr);

                hClntSock = accept(hServSock,(SOCKADDR*)&clntAdr,&addLen);
                handleInfo = (LPPER_HANDLE_DATA)malloc(sizeof(PER_HANDLE_DATA));
                handleInfo->hClntSock = hClntSock;

                memcpy(&(handleInfo->clntAdr),&clntAdr,addLen);

                CreateIoCompletionPort((HANDLE)hClntSock,hComPort,(DWORD)handleInfo,0);

                ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
                memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
                ioInfo->wsaBuf.len = BUF_SIZE;
                ioInfo->wsaBuf.buf = ioInfo->buffer;
                ioInfo->rwMode = READ;

                WSARecv(handleInfo->hClntSock,&(ioInfo->wsaBuf),1,&recvBytes,&flags,&(ioInfo->overlapped),NULL);

        }

        return 0;
}

//DWORD WINAPI EchoThreadMain(LPVOID pComPort)
unsigned __stdcall EchoThreadMain(LPVOID pComPort)
{
        HANDLE hComPort = (HANDLE)pComPort;
        SOCKET sock;
        DWORD bytesTrans;
        LPPER_HANDLE_DATA handleInfo;
        LPPER_IO_DATA ioInfo;
        DWORD flags = 0;

        while(1)
        {
                //GetQueuedCompletionStatus(hComPort,&bytesTrans,(LPDWORD)&handleInfo,(LPOVERLAPPED*)&ioInfo,INFINITE);
                GetQueuedCompletionStatus(hComPort, &bytesTrans, (PULONG_PTR)&handleInfo, (LPOVERLAPPED*)&ioInfo, INFINITE);
               
                sock = handleInfo->hClntSock;

                if (ioInfo->rwMode == READ)
                {
                        puts("message received!");
                        if (bytesTrans == 0)
                        {
                                closesocket(sock);
                                free(handleInfo);
                                free(ioInfo);
                                continue;
                        }

                        memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
                        ioInfo->wsaBuf.len = bytesTrans;
                        ioInfo->rwMode = WRITE;
                        WSASend(sock,&(ioInfo->wsaBuf),1,NULL,0,&(ioInfo->overlapped),NULL);

                        ioInfo = (LPPER_IO_DATA)malloc(sizeof(PER_IO_DATA));
                        memset(&(ioInfo->overlapped),0,sizeof(OVERLAPPED));
                        ioInfo->wsaBuf.len = BUF_SIZE;
                        ioInfo->wsaBuf.buf = ioInfo->buffer;
                        ioInfo->rwMode = READ;
                        WSARecv(sock,&(ioInfo->wsaBuf),1,NULL,&flags,&(ioInfo->overlapped),NULL);
                }
                else
                {
                        puts("message sent!");
                        free(ioInfo);
                }


        }
}[/mw_shl_code]

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|php中文网 | cnphp.com ( 赣ICP备2021002321号-2 )

GMT+8, 2024-11-22 03:01 , Processed in 0.288282 second(s), 33 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

申明:本站所有资源皆搜集自网络,相关版权归版权持有人所有,如有侵权,请电邮(fiorkn@foxmail.com)告之,本站会尽快删除。

快速回复 返回顶部 返回列表