zoukankan      html  css  js  c++  java
  • 一个worker thread服务一个客户端

    服务器端对一个客户端来了就开启一个工作线程,最多可接受64个。

    具体看代码:

    #pragma once
    #include <winsock.h>
    #include <stdio.h>
    
    #pragma comment(lib, "ws2_32.lib")
    
    #define MaxClient 64
    
    class MyTCPSocket
    {
    public:
        MyTCPSocket(void);
        ~MyTCPSocket(void);
        bool Init();
        bool UnInit();
        bool CreateSocket();
        bool Bind(unsigned aPost,const char* aAdress);
        bool Listen(int aBacklog=5);
        bool Connect(unsigned aPost,const char* aAdress);
        bool Send(const char* aBuf);
        bool Recv();
        void Accept();
        static DWORD WINAPI WorkerFun(PVOID aData);
    
    public:
        SOCKET m_ClientSocket[MaxClient];
    
    private:
        SOCKET m_Socket;
    
        sockaddr_in m_SockClientaddrIn ;
        HANDLE m_ClientHandle[MaxClient];
        CRITICAL_SECTION m_CriticalSection;
        DWORD m_Thread[MaxClient];
        int m_TotClient;
    };
    #include "MyTCPSocket.h"
    
    struct Para
    {
        MyTCPSocket* m_pMyTCPSocket;
        SOCKET m_CurSocket;
    };
    
    MyTCPSocket::MyTCPSocket(void)
    :m_Socket(INVALID_SOCKET)
    , m_TotClient(-1)
    {
        InitializeCriticalSection(&m_CriticalSection);
    }
    
    MyTCPSocket::~MyTCPSocket(void)
    {
        EnterCriticalSection(&m_CriticalSection);
        for (int i =0; i < m_TotClient;++i)
        {
            if (NULL != m_ClientHandle[i])
            {
                CloseHandle(m_ClientHandle[i]);
            }
        }
        LeaveCriticalSection(&m_CriticalSection);
    
        DeleteCriticalSection(&m_CriticalSection);
    }
    
    bool MyTCPSocket::Init()
    {
        int iResult;
        WORD wVersionRequested;
        WSADATA wsaData;
    
        wVersionRequested = MAKEWORD(2, 2);
        iResult = WSAStartup(wVersionRequested, &wsaData);
        if (iResult != 0) 
        {
            printf("WSAStartup failed with error: %d
    ", iResult);
            return false;
        } 
        else 
        {
            printf("WSAStartup succeeded!
    ");
            return true;
        }
    }
    
    bool MyTCPSocket::CreateSocket()
    {
        m_Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
        if (INVALID_SOCKET == m_Socket)
        {
            printf("INVALID_SOCKET
    ");
            return false;
        }
        printf("Create Socket(%d) successully.
    ",m_Socket);
        BOOL reuseaddr=TRUE;
        setsockopt(m_Socket,SOL_SOCKET,SO_REUSEADDR,(const char*)&reuseaddr,sizeof(reuseaddr));
        return true;
    }
    
    bool MyTCPSocket::Bind(unsigned aPost,const char* aAdress)
    {
        struct sockaddr_in server_addr;    // server address information
        server_addr.sin_family = AF_INET;         // host byte order
        server_addr.sin_port = htons(aPost);     // short, network byte order
        server_addr.sin_addr.s_addr = inet_addr(aAdress); // automatically fill with my IP
        memset(server_addr.sin_zero, '', sizeof(server_addr.sin_zero));
        if (-1 == bind(m_Socket,(struct sockaddr *)&server_addr,sizeof(server_addr)))
        {
            printf("Bind Error.
    ");
            return false;
        }
    
        int nRecvBuf = 32 * 1024; //设置为32K
        if (setsockopt(m_Socket,SOL_SOCKET,SO_RCVBUF,(const char*)&nRecvBuf,sizeof(int)) == -1) {
            perror("setsockopt");
            exit(1);
        }
        return true;
    }
    
    bool MyTCPSocket::Connect( unsigned aPost,const char* aAdress )
    {
        sockaddr_in lsockaddr_in;
        lsockaddr_in.sin_family = AF_INET;
        lsockaddr_in.sin_port = htons(aPost);
        lsockaddr_in.sin_addr.s_addr = inet_addr(aAdress);
    
        if (-1 == connect(m_Socket,(struct sockaddr *)&lsockaddr_in,sizeof(lsockaddr_in)))
        {
            printf("Conenct Error.
    ");
            return false;
        }
        return true;
    }
    
    bool MyTCPSocket::Listen( int aBacklog/*=5*/ )
    {
        if (-1 == listen(m_Socket,aBacklog))
        {
            printf("Listen Error.
    ");
            return false;
        }
        return true;
    }
    
    bool MyTCPSocket::Send( const char* aBuf)
    {
        if (-1 == send(m_Socket,aBuf,strlen(aBuf)+1,0))
        {
            printf("Send Error.
    ");
            return false;
        }
        return true;
    }
    
    bool MyTCPSocket::Recv()
    {
        //char lBuf[2048];
        //int lLength = 0;
        //lLength = recv(m_ClientSocket,lBuf,sizeof(lBuf),0);
        //if (SOCKET_ERROR == lLength || 0 == lLength)
        //{
        //    closesocket(m_ClientSocket);
        //    return false;
        //}
        //int lBegin = 0;
        //int lEnd = 0;
        //for (;lEnd < lLength;++lEnd)
        //{
        //    if ('' == lBuf[lEnd])
        //    {
        //        char lData[1024];
        //        int lLen = lEnd-lBegin;
        //        memcpy(lData,lBuf+lBegin,lLen+1);
        //        printf("We successfully received %d byte: %s.
    ", lLen, lData);
        //        lBegin = lEnd+1;
        //    }
        //}
        //if (lEnd < lLength)
        //{
        //    char lData[1024];
        //    memcpy(lData,lBuf+lBegin,lEnd-lBegin);
        //    lData[lEnd] = '';
        //    printf("We successfully received %d byte: %s.
    ", lData);
        //}
        //return true;
        return true;
    }
    
    bool MyTCPSocket::UnInit()
    {
        if (-1 == closesocket(m_Socket))
        {
            printf("Close Socket Error.
    ");
            return false;
        }
        printf("Close Socket(%d).
    ",m_Socket);
        return true;
    }
    
    void MyTCPSocket::Accept()
    {
        while(true)
        {
            int lAddrLen = sizeof(m_SockClientaddrIn);
    
            if (m_TotClient == MaxClient-1)
            {
                printf("Exceed max clients.
    ");
                break;
            }
    
            EnterCriticalSection(&m_CriticalSection);
            m_ClientSocket[++m_TotClient] = accept(m_Socket, (sockaddr*)&m_SockClientaddrIn,&lAddrLen);
            
            Para* lpPara = new Para;
            lpPara->m_pMyTCPSocket = this;
            lpPara->m_CurSocket = m_ClientSocket[m_TotClient];
            LeaveCriticalSection(&m_CriticalSection);
    
            printf("We successfully got a connection from %s:%d.
    ",
                inet_ntoa(m_SockClientaddrIn.sin_addr), ntohs(m_SockClientaddrIn.sin_port));
    
            m_ClientHandle[m_TotClient] = ::CreateThread(NULL, 0, WorkerFun,PVOID(lpPara), 0, &m_Thread[m_TotClient]);
    
            printf("Create WorkThread(%x) success.
    ",m_Thread[m_TotClient]);
        }
    }
    
    DWORD WINAPI MyTCPSocket::WorkerFun( PVOID aData )
    {
        if (NULL == aData)
        {
            printf("Exit Thread.
    ");
            return 0;
        }
    
        Para* lpPara = (Para*)(aData);
        MyTCPSocket* lTCPSocket = lpPara->m_pMyTCPSocket;
    
        if (lpPara->m_CurSocket == INVALID_SOCKET)
        {
            return 0;
        }
        
        while(true)
        {
            char lBuf[2048];
            int lLength = 0;
            lLength = recv(lpPara->m_CurSocket,lBuf,sizeof(lBuf),0);
            if (SOCKET_ERROR == lLength || 0 == lLength)
            {
                closesocket(lpPara->m_CurSocket);
                delete lpPara;
                printf("Exit Thread.
    ");
                return 0;
            }
            int lBegin = 0;
            int lEnd = 0;
            for (;lEnd < lLength;++lEnd)
            {
                if ('' == lBuf[lEnd])
                {
                    char lData[1024];
                    int lLen = lEnd-lBegin;
                    memcpy(lData,lBuf+lBegin,lLen+1);
                    printf("We successfully received %d byte: %s.
    ", lLen, lData);
                    lBegin = lEnd+1;
                }
            }
            if (lEnd < lLength)
            {
                char lData[1024];
                memcpy(lData,lBuf+lBegin,lEnd-lBegin);
                lData[lEnd] = '';
                printf("We successfully received %d byte: %s.
    ", lData);
            }
        }
    
        return 0;
    }

    表示是很简陋的写法,肯定还是有问题的,同步的地方没怎么想清楚,测试代码可以看上一篇的介绍,好吧,今天暂时先写到这里,尼玛,公司写神码软件申请书,搓的一逼。

  • 相关阅读:
    iOS中的UISearchBar
    iOS中的UIDatePicker 日期选择器
    iOS中的 深拷贝和浅拷贝
    iOS中的定时器实现图片的轮播
    iOS Crash文件的解析(一)
    iOS中的UIToolBar
    iOS中的瀑布流(RootCollectionViewControlle)
    iOS中NSThread(主线程,子线程)
    iOS中的串行,并行,分组,一次,障碍,延迟,反复执行(GCD)
    iOS中的动画
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/3324295.html
Copyright © 2011-2022 走看看