1. 头文件
#pragma once
#include <functional>
#include <sstream>
class CWinAsyncServer
{
public:
//ret 0: SUCCESS
//receiver和sender会运行在各自的线程中,其线程由这个函数内部启动。
int createServer(int port, std::function<void(SOCKET)>& receiver, std::function<void(SOCKET)>& sender, std::wostringstream& err);
int gets(std::string& str);
int puts(std::string& str);
private:
SOCKET _svSocket;
};
class CWinAsyncClient
{
public:
//ret 0: SUCCESS
//receiver和sender会运行在各自的线程中,其线程由这个函数内部启动。
int createClient(const char* hostAddr, int port, std::function<void(SOCKET)>& receiver, std::function<void(SOCKET)>& sender, std::wostringstream& err);
int gets(std::string& str);
int puts(std::string& str);
private:
SOCKET _cliSocket;
};
2. cpp文件
#include "pch.h"
#include <functional>
#include <signal.h>
#include <thread>
#include <winsock2.h>
#include "CASynWinSocket.h"
#pragma comment(lib, "ws2_32.lib")
//Bind => id address size
//connect => socket, structure(ipv4, address, port), structure size)
//listen => socket 1(no. of tcp connections that can be queued on server)
//send => socket buffer length flags
// recv => socket , buffer , size , flags
int CWinAsyncServer::createServer(int port, std::function<void(SOCKET)>& receiver, std::function<void(SOCKET)>& sender, std::wostringstream& err)
{
_svSocket = INVALID_SOCKET;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
if (iResult != NO_ERROR)
{
err << L"WSAStartup Error";
return -1;
}
_svSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_svSocket == INVALID_SOCKET)
{
err << L"Error at socket(): " << WSAGetLastError();
WSACleanup();
return -2;
}
SOCKET s = socket(AF_INET, SOCK_STREAM, 0);
if (s == INVALID_SOCKET)
{
err << L"Error at socket(0): " << WSAGetLastError();
WSACleanup();
return -3;
}
struct sockaddr_in sock_info;
sock_info.sin_family = AF_INET;
sock_info.sin_addr.s_addr = INADDR_ANY;
sock_info.sin_port = htons(port);
if (bind(_svSocket, (SOCKADDR*)&sock_info, sizeof(sock_info)) == SOCKET_ERROR)
{
err << L"bind() failed.\n";
closesocket(_svSocket);
return -4;
}
if (listen(_svSocket, 1) == SOCKET_ERROR)
{
err << L"Error listening on socket.\n";
return -5;
}
SOCKET AcceptSocket;
while (1)
{
AcceptSocket = SOCKET_ERROR;
while (AcceptSocket == SOCKET_ERROR)
{
AcceptSocket = accept(_svSocket, NULL, NULL);
}
_svSocket = AcceptSocket;
break;
}
std::thread th1(receiver, _svSocket);
std::thread th2(sender, _svSocket);
th1.join();
th2.join();
closesocket(_svSocket);
return 0;
}
int CWinAsyncServer::gets(std::string& str)
{
str.clear();
char buf[4096] = "";
int bytesRecv = recv(_svSocket, buf, 1000, 0);
if (bytesRecv > 0)
str = buf;
return bytesRecv;
}
int CWinAsyncServer::puts(std::string& str)
{
return send(_svSocket, str.c_str(), str.length(), 0);
}
int CWinAsyncClient::createClient(const char* hostAddr, int port, std::function<void(SOCKET)>& receiver, std::function<void(SOCKET)>& sender, std::wostringstream& err)
{
_cliSocket = INVALID_SOCKET;
WSADATA wsaData;
int iResult = WSAStartup(MAKEWORD(2, 2),
&wsaData);
if (iResult != NO_ERROR)
{
err << L"WSAStartup Error";
return -1;
}
_cliSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (_cliSocket == INVALID_SOCKET)
{
err << L"Error at socket(): " << WSAGetLastError();
WSACleanup();
return -2;
}
SOCKET s = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in clientService;
clientService.sin_family = AF_INET;
clientService.sin_addr.s_addr = inet_addr(hostAddr); //"127.0.0.1"
clientService.sin_port = htons(port);
if (connect(_cliSocket, (SOCKADDR*)&clientService, sizeof(clientService)) == SOCKET_ERROR)
{
err << "Failed to connect.\n";
WSACleanup();
return -3;
}
std::thread th1(receiver, _cliSocket);
std::thread th2(sender, _cliSocket);
th1.join();
th2.join();
closesocket(_cliSocket);
return 0;
}
int CWinAsyncClient::gets(std::string& str)
{
str.clear();
char buf[4096] = "";
int bytesRecv = recv(_cliSocket, buf, 1000, 0);
if (bytesRecv > 0)
str = buf;
return bytesRecv;
}
int CWinAsyncClient::puts(std::string& str)
{
return send(_cliSocket, str.c_str(), str.length(), 0);
}
|