День добрый, пытаюсь разобраться со следующей программой:
#pragma once
#pragma comment(lib, "WS2_32.lib")
#include <ws2tcpip.h>
#include <string>
#include <winsock2.h>
#include <iostream>
#include <conio.h>
class TCPSocket
{
public:
enum SOCKET_STATE {INACTIVE,LISTENING,CONNECTED};
TCPSocket();
virtual ~TCPSocket();
static void Startup();
static void Cleanup();
int Listen(const unsigned short listenPort);
int Connect(const std::string& connectAddress,const unsigned short connectPort);
int Accept(TCPSocket* pAcceptSocket);
int Send(const char* dataBuffer,const int dataLength,const bool fixedLength=false);
int Receive(char* dataBuffer,const int dataLength,const bool fixedLength=false);
int Shutdown();
std::string GetAddress();
inline TCPSocket::SOCKET_STATE State();
protected:
private:
static bool wsaStarted;
static WSADATA wsaData;
SOCKET m_socket;
sockaddr_in m_socketAddress;
socklen_t m_addressLength;
TCPSocket::SOCKET_STATE m_socketState;
};
#include "tcp_socket.h"
bool TCPSocket::wsaStarted=false;
WSADATA TCPSocket::wsaData=WSADATA();
TCPSocket::TCPSocket()
{
if(!TCPSocket::wsaStarted) TCPSocket::Startup();
this->m_socket=INVALID_SOCKET;
memset(static_cast<void*>(&this->m_socketAddress),0,sizeof(this->m_socketAddress));
this->m_addressLength=sizeof(this->m_socketAddress);
this->m_socketState=TCPSocket::INACTIVE;
}
TCPSocket::~TCPSocket()
{
if(this->m_socket!=INVALID_SOCKET) this->Shutdown();
}
void TCPSocket::Startup()
{
if(!TCPSocket::wsaStarted)
{
TCPSocket::wsaStarted=true;
::WSAStartup(WINSOCK_VERSION,&wsaData);
}
}
void TCPSocket::Cleanup()
{
if(TCPSocket::wsaStarted)
{
TCPSocket::wsaStarted=false;
::WSACleanup();
}
}
int TCPSocket::Listen(const unsigned short listenPort)
{
if(this->m_socketState!=TCPSocket::INACTIVE) return -1;
this->m_socketAddress.sin_family=AF_INET;
this->m_socketAddress.sin_addr.S_un.S_addr=ADDR_ANY;
this->m_socketAddress.sin_port=htons(listenPort);
this->m_socket=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(this->m_socket==INVALID_SOCKET) return ::WSAGetLastError();
if(::bind(this->m_socket,reinterpret_cast<sockaddr*>(&this->m_socketAddress),this->m_addressLength)==SOCKET_ERROR) return ::WSAGetLastError();
if(::listen(this->m_socket,SOMAXCONN)==SOCKET_ERROR) return ::WSAGetLastError();
this->m_socketState=TCPSocket::LISTENING;
return 0;
}
int TCPSocket::Connect(const std::string& connectAddress,const unsigned short connectPort)
{
if(this->m_socketState!=TCPSocket::INACTIVE) return -1;
this->m_socketAddress.sin_family=AF_INET;
this->m_socketAddress.sin_addr.S_un.S_addr=::inet_addr(connectAddress.c_str());
if(this->m_socketAddress.sin_addr.S_un.S_addr==INADDR_NONE)
{
hostent* pHost;
pHost=::gethostbyname(connectAddress.c_str());
if(pHost!=nullptr)
if(pHost->h_name!=nullptr)
if(pHost->h_addr_list!=nullptr)
if((*(pHost->h_addr_list))!=nullptr)
this->m_socketAddress.sin_addr.S_un.S_addr=*reinterpret_cast<int*>(*(pHost->h_addr_list));
}
this->m_socketAddress.sin_port=htons(connectPort);
this->m_socket=::socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(this->m_socket==INVALID_SOCKET) return ::WSAGetLastError();
if(::connect(this->m_socket,reinterpret_cast<sockaddr*>(&this->m_socketAddress),this->m_addressLength)==SOCKET_ERROR) return ::WSAGetLastError();
this->m_socketState=TCPSocket::CONNECTED;
return 0;
}
int TCPSocket::Accept(TCPSocket* pAcceptSocket)
{
if(pAcceptSocket==nullptr) pAcceptSocket=new TCPSocket();
if(pAcceptSocket->m_socketState!=TCPSocket::INACTIVE) return -1;
pAcceptSocket->m_socket=::accept(this->m_socket,reinterpret_cast<sockaddr*>(&pAcceptSocket->m_socketAddress),&pAcceptSocket->m_addressLength);
if(pAcceptSocket->m_socket==INVALID_SOCKET) return ::WSAGetLastError();
pAcceptSocket->m_socketState=TCPSocket::CONNECTED;
return 0;
}
int TCPSocket::Send(const char* dataBuffer,const int dataLength,const bool fixedLength)
{
int socketLength;
if(this->m_socketState!=TCPSocket::CONNECTED) return -1;
if(fixedLength)
{
socketLength=::send(this->m_socket,dataBuffer,dataLength,0);
if((socketLength==SOCKET_ERROR)||(socketLength!=dataLength)) return ::WSAGetLastError();
}
else
{
int data_index=0;
int data_length=dataLength;
while(data_length>0)
{
socketLength=::send(this->m_socket,dataBuffer+data_index,data_length,0);
if(socketLength==SOCKET_ERROR) return ::WSAGetLastError();
data_index+=socketLength;
data_length-=socketLength;
}
}
return 0;
}
int TCPSocket::Receive(char* dataBuffer,const int dataLength,const bool fixedLength)
{
int socketLength;
if(this->m_socketState!=TCPSocket::CONNECTED) return -1;
if(fixedLength)
{
socketLength=::recv(this->m_socket,dataBuffer,dataLength,0);
if((socketLength==SOCKET_ERROR)||(socketLength!=dataLength)) return ::WSAGetLastError();
}
else
{
int data_index=0;
int data_length=dataLength;
while(data_length>0)
{
socketLength=::recv(this->m_socket,dataBuffer+data_index,data_length,0);
if(socketLength==SOCKET_ERROR) return ::WSAGetLastError();
data_index+=socketLength;
data_length-=socketLength;
}
}
return 0;
}
int TCPSocket::Shutdown()
{
int errCode=0;
switch(this->m_socketState)
{
case TCPSocket::INACTIVE:
errCode=-1;
break;
case TCPSocket::LISTENING:
if(::closesocket(this->m_socket)==SOCKET_ERROR) errCode=::WSAGetLastError();
break;
case TCPSocket::CONNECTED:
if((::shutdown(this->m_socket,SD_BOTH)==SOCKET_ERROR)||(::closesocket(this->m_socket)==SOCKET_ERROR)) errCode=::WSAGetLastError();
break;
}
this->m_socket=INVALID_SOCKET;
return errCode;
}
std::string TCPSocket::GetAddress()
{
char buf[_MAX_INT_DIG*2];
sprintf(buf,"%d",::ntohs(this->m_socketAddress.sin_port));
return std::string(::inet_ntoa(this->m_socketAddress.sin_addr))+":"+std::string(buf);
}
inline TCPSocket::SOCKET_STATE TCPSocket::State()
{
return this->m_socketState;
}
По идее, сначала запускаем сервер на прослушивание:
TCPSocket* server = new TCPSocket();
server->Listen(27013);
А потом коннектимся к нему:
TCPSocket* client = new TCPSocket();
сlient->Connect("127.0.0.1", 27013);
Но не совсем понятна роль TCPSocket::Accept (на мсдн написано, что функция грубо говоря создает новый сокет с текущим подключением)... Можете вкратце, на пальцах, объяснить последовательность действий(и сами действия)
Сильно не пинайте, я новичок в клиент-серверном программировании