Socket Client

2024. 4. 10. 02:15C++

///SocketClient.h

 

#pragma once

#include <WinSock2.h>
#include <MSWSock.h>
#include <WS2tcpip.h>
#include <string>

#define SOCKET_BUFFER_SIZE 2048

class SocketClient
{
public:
    char buffer[SOCKET_BUFFER_SIZE];
    std::string address;
    int port;
    int connect_status;

    WSAData wsaData;
    SOCKET clientSocket;
    SOCKADDR_IN serverAddr;

public:
    SocketClient();
    void Connect(std::string Address, int Port);
    void Close();
    void Send(std::string Message);
    void ReceiveThread();
};

typedef void(*SOCKET_CALLBACK_FUNC)(char*, int);
void RegisterSocketCallback(SOCKET_CALLBACK_FUNC cb);
void ReleaseSocketCallback();
void FireSocketCallback(char* message, int size);

 

 

///SocketClient.cpp

 

#include "SocketClient.h"
#include <thread>
#pragma comment(lib, "ws2_32.lib")

// Callback
static SOCKET_CALLBACK_FUNC CBF = nullptr;

SocketClient::SocketClient()
{
     connect_status = -1;
     memset(buffer, 0, SOCKET_BUFFER_SIZE);
     memset(&serverAddr, 0, sizeof(serverAddr));
}

void SocketClient::Connect(std::string Address, int Port)
{
     address = Address;
     port = Port;

     if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) return;

     clientSocket = socket(AF_INET, SOCK_STREAM, 0);
     if (clientSocket == INVALID_SOCKET) 
     {
          int errorCode = WSAGetLastError();
          printf("Socket ErrorCode %d\n", errorCode);
          return;
     }

     serverAddr.sin_family = AF_INET;
     serverAddr.sin_port = htons(port);

     inet_pton(AF_INET, address.c_str(), &serverAddr.sin_addr);
     connect_status = connect(clientSocket, (SOCKADDR*)&serverAddr, sizeof(serverAddr));

     if (connect_status == SOCKET_ERROR) 
     {
          int errCode = WSAGetLastError();
          printf("Connect ErrorCode %d\n", errCode);
          return;
     }

     std::thread t = std::thread(&SocketClient::ReceiveThread, this);
     t.detach();
}

void SocketClient::Close()
{
     if (connect_status == 0)
     {
          connect_status = -1;
          closesocket(clientSocket);
          WSACleanup();
     }
}

void SocketClient::Send(std::string Message)
{
     send(clientSocket, Message.c_str(), Message.size(), 0);
}

void SocketClient::ReceiveThread()
{
     printf("Socket read start...\n");
     while (true)
     {
          int rcvBytes = recv(clientSocket, buffer, SOCKET_BUFFER_SIZE, 0);
          if (rcvBytes > 0)
          {
               FireSocketCallback(buffer, rcvBytes);
               printf("%s\n", buffer);
          }
          if (rcvBytes == 0) break;
     }
     printf("Socket read end\n");
}

////////////////////////////////////////////////////////////////////////////////////////////
//  Callback 함수
////////////////////////////////////////////////////////////////////////////////////////////

void RegisterSocketCallback(SOCKET_CALLBACK_FUNC cb)
{
     CBF = cb;
}
void ReleaseSocketCallback()
{
     CBF = nullptr;
}
void FireSocketCallback(char* message, int size)
{
     if (CBF) CBF(message, size);
}

'C++' 카테고리의 다른 글

sqlite 사용하기  (0) 2024.04.21