zoukankan      html  css  js  c++  java
  • 封装naive socket

    周五去一个公司打了个酱油,面试官问我:你封装过socket没?

    言下之意是问我实际写过底层代码没,我悻悻地说写过点。

    PS:说实话木有封装过,今天无聊就来封装下。

    话说写了这么久C++,底层用c来写还是灰常爽的,C++把它包起来很好看而且好用。

    嗯嗯,言归正传,创建了MyTCPSocket:

    问题记录1:一旦来了新的链接,就创建一个work线程来处理,但是遇到了小问题:

    #pragma once
    #include <winsock.h>
    #include <stdio.h>
    
    #pragma comment(lib, "ws2_32.lib")
    
    static DWORD WINAPI WorkerFun(LPVOID aData);
    
    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();
    
    private:
        SOCKET m_Socket;
        SOCKET m_ClientSocket;
        sockaddr_in m_SockClientaddrIn ;
    };
    #include "MyTCPSocket.h"
    
    MyTCPSocket::MyTCPSocket(void)
    :m_Socket(INVALID_SOCKET)
    {
    }
    
    MyTCPSocket::~MyTCPSocket(void)
    {
    }
    
    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;
    }
    
    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()
    {
        int lAddrLen = sizeof(m_SockClientaddrIn);
        m_ClientSocket = accept(m_Socket, (sockaddr*)&m_SockClientaddrIn,&lAddrLen);
    
        printf("We successfully got a connection from %s:%d.
    ",
            inet_ntoa(m_SockClientaddrIn.sin_addr), ntohs(m_SockClientaddrIn.sin_port));
    
        HANDLE handle = ::CreateThread(NULL, 0, WorkerFun,NULL, 0, NULL);
    }
    
    DWORD WINAPI WorkerFun( LPVOID aData )
    {
        printf("Create Worker Thread.
    ");
    
        SOCKET lSocket = (SOCKET)(aData);
    
        char lBuf[2048];
        int lLength = 0;
        lLength = recv(lSocket,lBuf,sizeof(lBuf),0);
        if (SOCKET_ERROR == lLength || 0 == lLength)
        {
            closesocket(lSocket);
            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 0;
    }

    测试代码:

    #include <stdio.h>
    
    #include "MyTCPSocket.h"
    
    void ServerStart() 
    {
        MyTCPSocket lServer;
        lServer.Init();
        lServer.CreateSocket();
        lServer.Bind(1234,"192.168.28.1");
        lServer.Listen();
        lServer.Accept();
    
        while(1)
        {
            if (!lServer.Recv())
            {
                break;
            }
        }
        lServer.UnInit();
    }
    
    void ClientStart()
    {
        MyTCPSocket lServer;
        lServer.Init();
        lServer.CreateSocket();
        if (!lServer.Connect(1234,"192.168.28.1"))
        {
            lServer.UnInit();
            return;
        }
        for (int i =0; i <10;++i)
        {
            lServer.Send("hell0");
        }
        lServer.UnInit();
    }
    int main()
    {
        ServerStart();
    }

    表示只是刚开始瞎写,很丑 有木有,赶快改进 有木有!

    不过经测试,还是不错滴,博客园有大侠封装的更好的木有,写代码不想注释啊,介个可不可以上首页,大侠猛戳呀,哈哈!

  • 相关阅读:
    一个简短的yahoo YUI介绍
    备忘录
    海量数据库查询
    asp.net webshell 解决 方案
    IE=EmulateIE7 标签的作用
    WINDOWS 2003 IIS网站防木马权限设置安全配置整理
    C语言各种函数
    虚函数的各种情况
    equals与==关于Object覆盖和重载问题
    类型转换函数转换为构造类型
  • 原文地址:https://www.cnblogs.com/xiangshancuizhu/p/3323262.html
Copyright © 2011-2022 走看看