zoukankan      html  css  js  c++  java
  • 网络学习杂七杂八

    一些杂七杂八的测试代码就放这里了 做个索引记录

    1 IOCP

    从windows网络编程 第八章 获取的C语言版本代码

    如果想学习 可以搜搜 “ 小猪 PIGGYXP iocp” “windows网络编程 iocp ” 应该有所收获

    自己从头写了一遍c++ 以便加深记忆 

    #pragma once
    #include "WSAManager.h"
    #include "windows.h"
    #include <thread>
    #include <vector>
    
    const int defaultPortNum = 8893;
    const int defaultThreadNum = 1;
    
    #define CLOSEHANDLE(x) if(NULL != (x) && INVALID_HANDLE_VALUE != (x) ){CloseHandle(x);x = NULL;}
    #define CLOSESOCKET(x) if(INVALID_SOCKET != (x)){closesocket(x);x = INVALID_SOCKET;}
    
    
    const int defaultBufSize = 8192;
    
    typedef struct
    {
        OVERLAPPED Overlapped;
        WSABUF DataBuf;
        CHAR Buffer[defaultBufSize];
        DWORD BytesSEND;
        DWORD BytesRECV;
    } PER_IO_OPERATION_DATA, *LPPER_IO_OPERATION_DATA;
    
    
    typedef struct
    {
        SOCKET Socket;
    } PER_HANDLE_DATA, *LPPER_HANDLE_DATA;
    
    
    class IOCPModel {
    public:
        IOCPModel(int portNum = defaultPortNum):
            completionPort_(NULL),
            threadNum_(defaultThreadNum),
            pthrArray_(NULL),
            listenSock_(INVALID_SOCKET),
            thrExitFlag_(true)
        {
            portNum_ = portNum;
        }
    
        ~IOCPModel()
        {
            StopThread();
            CLOSEHANDLE(completionPort_);
            CLOSESOCKET(listenSock_);
        }
    
        bool Start();
        bool Init();
        bool ServerWorkerThread(void* CompletionPortID);
        bool StartThread(int thrNum = defaultThreadNum);
        bool StopThread();
        bool ListenBindOrDie();
        bool AcceptPostSocket();
        void DeleteHandleData(PER_HANDLE_DATA* PerHandleData);
        void DeleteIoData(PER_IO_OPERATION_DATA* PerIoData);
    private:
        std::vector<PER_HANDLE_DATA*> perHandleDataVec_;
        std::vector<PER_IO_OPERATION_DATA*> perIOOperationDataVec_;
        WSAManager wsaManager_;
        HANDLE completionPort_;
        int portNum_;
        std::thread* pthrArray_;
        int threadNum_;
        bool thrExitFlag_;
        SOCKET listenSock_;
    };
    View Code
    #pragma once
    #include "IocpModel.h"
    #include <iomanip>
    
    bool IOCPModel::AcceptPostSocket()
    {
        SOCKET acceptSock;
    
        if ((acceptSock = WSAAccept(listenSock_, NULL, NULL, NULL, 0)) == SOCKET_ERROR)
        {
            std::cerr << "WSAAccept() failed with error " << WSAGetLastError() << std::endl;
            return false;
        }
    
        PER_HANDLE_DATA* pHandleData = new PER_HANDLE_DATA;
        if (NULL == pHandleData)
        {
            std::cerr << __FUNCTION__ <<  ".  PER_HANDLE_DATA malloc failed" << std::endl;
            return false;
        }
        pHandleData->Socket = acceptSock;
        perHandleDataVec_.push_back(pHandleData);
    
        if ( CreateIoCompletionPort((HANDLE)acceptSock, completionPort_, (ULONG_PTR)pHandleData, 0) 
            == NULL)
        {
            std::cerr << __FUNCTION__ << ".  CreateIoCompletionPort  failed" << std::endl;
            return false;
        }
    
        PER_IO_OPERATION_DATA* PerIoData = new PER_IO_OPERATION_DATA;
        if (NULL == PerIoData)
        {
            std::cerr << __FUNCTION__ << ".  PER_IO_OPERATEION_DATA malloc failed" << std::endl;
            return false;
        }
        ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
        PerIoData->BytesSEND = 0;
        PerIoData->BytesRECV = 0;
        PerIoData->DataBuf.len = defaultBufSize;
        PerIoData->DataBuf.buf = PerIoData->Buffer;
    
        perIOOperationDataVec_.push_back(PerIoData);
        DWORD Flags = 0;
        DWORD RecvBytes = 0;
        if (WSARecv(acceptSock, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
            &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
        {
            if (WSAGetLastError() != ERROR_IO_PENDING)
            {
                std::cerr << __FUNCTION__ << ".  WSARecv() failed with error " << WSAGetLastError() << std::endl;
                return false;
            }
        }
    
        return true;
    }
    
    bool IOCPModel::Start()
    {
        if (false == Init())
        {
            return false;
        }
    
        while (true)
        {
            if (false == AcceptPostSocket())
                break;
        }
    
        return true;
    }
    bool IOCPModel::StartThread(int thrNum )
    {
        pthrArray_ = new std::thread[thrNum];
        if (NULL == pthrArray_)
        {
            std::cerr << "new thread error" << std::endl;
            return false;
        }
        
        thrExitFlag_ = false;
        threadNum_ = thrNum;
        for (int i = 0; i < threadNum_; i++)
        {
            pthrArray_[i] = std::thread(&IOCPModel::ServerWorkerThread, this, completionPort_);
        }
    
        return true;
    }
    
    
    bool IOCPModel::StopThread()
    {
        thrExitFlag_ = true;
        for (int i = 0; i < threadNum_; i++)
        {
            pthrArray_[i].join();
        }
    
        if (NULL != pthrArray_)
        {
            delete[] pthrArray_;
        }
        return true;
    }
    
    bool IOCPModel::ListenBindOrDie()
    {
        if ((listenSock_ = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0,
            WSA_FLAG_OVERLAPPED)) == INVALID_SOCKET)
        {
            std::cerr << __FUNCTION__ << ". Create listenSock_ failed  "<< std::endl;
            return false;
        }
        SOCKADDR_IN InternetAddr;
        InternetAddr.sin_family = AF_INET;
        InternetAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        InternetAddr.sin_port = htons(portNum_);
    
        if (bind(listenSock_, (PSOCKADDR)&InternetAddr, sizeof(InternetAddr)) == SOCKET_ERROR)
        {
            std::cerr << __FUNCTION__ << ". bind() failed with error  " << WSAGetLastError() << std::endl;
            return false;
        }
    
        if (listen(listenSock_, 5) == SOCKET_ERROR)
        {
            std::cerr << __FUNCTION__ << ". listen() failed with error  " << WSAGetLastError() << std::endl;
            return false;
        }
    
        return true;
    }
    
    bool IOCPModel::Init()
    {
        if ( (completionPort_ =
            CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0)
             ) == NULL)
        {
            std::cerr << __FUNCTION__ <<  ". CreateIoCompletionPort failed with error:  " <<  GetLastError() << std::endl;
            return false ;
        }
    
        if (false == StartThread(1))
        {
            std::cerr << __FUNCTION__ << ". CreateIoCompletionPort failed with error:  " << GetLastError() << std::endl;
            return false;
        }
    
        if (false == ListenBindOrDie())
        {
            return false;
        }
    
        return true;
    }
    
    void IOCPModel::DeleteHandleData(PER_HANDLE_DATA* PerHandleData)
    {
        // todo 
        delete PerHandleData;
    }
    
    
    void IOCPModel::DeleteIoData(PER_IO_OPERATION_DATA* PerIoData)
    {
        //todo
        delete PerIoData;
    }
    
    
    
    
    bool IOCPModel::ServerWorkerThread(void* completionPortID)
    {
        HANDLE CompletionPort = (HANDLE)completionPortID;
        DWORD BytesTransferred;
        //LPOVERLAPPED Overlapped;
        LPPER_HANDLE_DATA PerHandleData;
        LPPER_IO_OPERATION_DATA PerIoData;
        DWORD SendBytes, RecvBytes;
        DWORD Flags;
    
        while (!thrExitFlag_)
        {
            if (GetQueuedCompletionStatus(CompletionPort, &BytesTransferred,
                (LPDWORD)&PerHandleData, (LPOVERLAPPED *)&PerIoData, INFINITE) == 0)
            {
                std::cerr << __FUNCTION__ << ". GetQueuedCompletionStatus failed with error"
                    << GetLastError() << std::endl;
                return false;
            }
    
            if (0 == BytesTransferred)
            {
                std::cerr << "close socket " << PerHandleData->Socket << std::endl;
                CLOSESOCKET(PerHandleData->Socket);
    
                DeleteHandleData(PerHandleData);
                DeleteIoData(PerIoData);
                continue;
            }
    
            // only for test
            {
                //再次投递
                Flags = 0;
                ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
    
                PerIoData->DataBuf.len = defaultBufSize;
                PerIoData->DataBuf.buf = PerIoData->Buffer;
                std::cout << std::setw(BytesTransferred) << PerIoData->DataBuf.buf << std::endl;
    
                if (WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
                    &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
                {
                    if (WSAGetLastError() != ERROR_IO_PENDING)
                    {
                        printf("WSARecv() failed with error %d\n", WSAGetLastError());
                        return 0;
                    }
                }
    
    
            }
    
            /*
            if (PerIoData->BytesRECV == 0)
            {
                PerIoData->BytesRECV = BytesTransferred;
                PerIoData->BytesSEND = 0;
            }
            else
            {
                PerIoData->BytesSEND += BytesTransferred;
            }
    
            if (PerIoData->BytesRECV > PerIoData->BytesSEND)
            {
    
                // Post another WSASend() request.
                // Since WSASend() is not gauranteed to send all of the bytes requested,
                // continue posting WSASend() calls until all received bytes are sent.
    
                ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
    
                PerIoData->DataBuf.buf = PerIoData->Buffer + PerIoData->BytesSEND;
                PerIoData->DataBuf.len = PerIoData->BytesRECV - PerIoData->BytesSEND;
    
                if (WSASend(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &SendBytes, 0,
                    &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
                {
                    if (WSAGetLastError() != ERROR_IO_PENDING)
                    {
                        printf("WSASend() failed with error %d\n", WSAGetLastError());
                        return 0;
                    }
                }
            }
            else
            {
                PerIoData->BytesRECV = 0;
    
                // Now that there are no more bytes to send post another WSARecv() request.
    
                Flags = 0;
                ZeroMemory(&(PerIoData->Overlapped), sizeof(OVERLAPPED));
    
                PerIoData->DataBuf.len = defaultBufSize;
                PerIoData->DataBuf.buf = PerIoData->Buffer;
    
                if (WSARecv(PerHandleData->Socket, &(PerIoData->DataBuf), 1, &RecvBytes, &Flags,
                    &(PerIoData->Overlapped), NULL) == SOCKET_ERROR)
                {
                    if (WSAGetLastError() != ERROR_IO_PENDING)
                    {
                        printf("WSARecv() failed with error %d\n", WSAGetLastError());
                        return 0;
                    }
                }
            }
            */
    
    
        }
    
    
    
    
        return true;
    }
    View Code
    // MyIocp.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include "IocpModel.h"
    
    
    int main()
    {
        IOCPModel iocpServer(8892);
        iocpServer.Start();
    
        IOCPModel iocpServer_another;
        iocpServer_another.Start();
    
        return 0;
    }

    2 待续.......

  • 相关阅读:
    Django学习过程中遇到的问题
    代理工具WebScarab安装(转载)
    MongoDB安装之window版本的安装
    QT打包
    小工具--串口
    多线程--信号量
    关于多线程
    QQ界面及简单操作实现
    udp通信
    char *p = "abc";char p[] = "abc";两者之间的区别
  • 原文地址:https://www.cnblogs.com/itdef/p/5396174.html
Copyright © 2011-2022 走看看