select客户端模型封装——回调方式快速建立客户端

SockClient.h

#pragma once

#include<functional>

#define _WINDOWS
#ifdef _WINDOWS
    #define _WINSOCK_DEPRECATED_NO_WARNINGS 
    #ifndef _WINSOCK2_H
        #include<WinSock2.h>
        #pragma comment(lib,"ws2_32.lib")
    #endif
    #ifndef _WINDOWS_H
        #include<Windows.h>
    #endif
#endif

class SocketClient
{
private :
    struct sockaddr_in ServerAddr;
    SOCKET s;
    bool stopFlag = false;

public:
    SocketClient();
    ~SocketClient();
    int connectServer(char *addr,int port);
    int sendToServer(char *buf, int len);
    int recvFromServer(char *buf, int len);
    void startRecv(std::function<void ()> recvEvent,std::function<void()> breakEvent);
};

SocketClient.cpp

#include "SocketClient.h"

SocketClient::SocketClient()
{
    WORD var = MAKEWORD(2, 2);
    WSADATA wsaData;
    WSAStartup(var, &wsaData);

    this->s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    this->ServerAddr.sin_family = AF_INET;

}


SocketClient::~SocketClient()
{
    closesocket(s);
    WSACleanup();
}

/*
*
*    连接到客户端
*    成功返回0 失败返回-1    
*
*/
int SocketClient::connectServer(char * addr, int port)
{
    this->ServerAddr.sin_port = htons(port);
    this->ServerAddr.sin_addr.S_un.S_addr = inet_addr(addr);

    int ret = connect(s, (const sockaddr*)&this->ServerAddr, sizeof(struct sockaddr_in));

    return ret;
}

int SocketClient::sendToServer(char * buf, int len)
{
    return send(this->s, buf, len, 0);
}

int SocketClient::recvFromServer(char * buf, int len)
{
    return recv(this->s, buf, len, 0);
}

void SocketClient::startRecv(std::function<void()> recvEvent, std::function<void()> breakEvent)
{
    this->stopFlag = true;
    while (true)
    {
        if (stopFlag)break;

        fd_set readSet;
        FD_ZERO(&readSet);
        FD_SET(this->s, &readSet);

        int ret = select(this->s, &readSet, 0, 0, 0);

        if (ret < 0) {
            //Connect breaks
            breakEvent();
            break;
        }
        else if (ret == 0) {
            //No Message
            continue;
        }
        //Have Message
        if (FD_ISSET(&readSet, this->s))
        {
            FD_CLR(this->s, &readSet);
            recvEvent();
        }
    }
}

main.cpp

#include <iostream>
#include <cstring>
#include <functional>

#define _WINDOWS

#include "SocketClient.h"

using namespace std;

char IP[] = "127.0.0.1";
int Port = 2019;
int abc;

int main()
{
    SocketClient *Client = new SocketClient();
    cout << "正在连接..." << endl;
    if (Client->connectServer(IP, Port) != 0)
    {
        cout<< "连接失败" <<endl;
        cin >> abc;
        return 0;
    }
    cout << "连接成功" << endl;
    Client->startRecv([Client]() -> void {
        char buf[1024];
        int n = Client->recvFromServer(buf, 1024);
        if (n > 0) {
            buf[n] = '';
            cout << "Recv: " << buf << endl;
        }
    }, []() -> void {
        cout << "Connect break;" << endl;
    });
    cin >> abc;
    return 0;
}
原文地址:https://www.cnblogs.com/HadesBlog/p/11805381.html