PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : CNetConn


Bluesteel
11.03.2009, 11:44
So hier hab ich noch was extrem feines für die jenigen die sich mit Net conn auseinander setzen^^
Provides WinSock2 IP connection management wenn euch das was sagt :)

/*

Provides WinSock2 IP connection management



Dependencies: CCrypto (discardable), CString, wsock32.lib





*/



#ifndef _NETCONN_H_INC_

#define _NETCONN_H_INC_



#include <windows.h>

#include <winsock.h>

#include "string.h"

#include "crypto.h"



#define MAX_CLIENT_CONN 10 // maximum possible connections from clients

// used in NetListenThread()

extern int giCurrConnCount;



/*

* class CNetConn

*

* Provides generic network communication layer with GK/HTTP/FTP protocol support

*

*/

class CNetConn

{

public:

// Main constructor

// Initializes class and some variables

CNetConn();



// Main destructor

~CNetConn();



// create socket and bind it if port != 0

BOOL CreateSocket(int iType, int iPort);

// opens a connection

BOOL Connect(CString strHost);

// closes connection

void Close();

// gets pending connection ob bound listen port

// --> result must be checked with IsValid() method!!

CNetConn GetConn();



// send string data to remote computer

int Send(CString str);

// send binary data to remote computer

int SendData(LPVOID data, DWORD dwLength);

// receive data from remote computer

int Recv(CString& str, int iMaxLen);



// is a valid/connected socket?

BOOL IsValid();

BOOL IsConnected();



// encryption

int SetEncryption(int iMethod);



CString m_strHost;

sockaddr_in m_addr;



private:

SOCKET m_socket;

WSADATA m_wsaData;

bool m_bIsConnected;

//CCrypto m_crypto;

};



#define NETNOTIFY_OPEN 0

#define NETNOTIFY_DATA 1

#define NETNOTIFY_CLOSE 2

typedef int (*NETNOTIFYPROC)(CNetConn *, CString, int);



struct RECV_PARAM

{

CNetConn *conn;

NETNOTIFYPROC *pNetNotify;

};



HANDLE InitNetConnThread(CNetConn *conn, NETNOTIFYPROC *pNetNotify, DWORD *tid);

HANDLE InitNetListenThread(CNetConn *listenconn, NETNOTIFYPROC *pNetNotify, DWORD *tid);



#endif // ifdef _NETCONN_H_INC_
/*

Provides WinSock2 IP connection management



Dependencies: CCrypto (discardable), CString, wsock32.lib





*/



#include "netconn.h"

//#include "crypto.h"



/*

* default constructor

*

*/

CNetConn::CNetConn()

{

if (WSAStartup(0x202, &m_wsaData) == SOCKET_ERROR)

{

WSACleanup();

DEBUGMSG("CNetConn couldn't init windows sockets. Quitting process");

ExitProcess(0);

}



m_socket = INVALID_SOCKET;

m_bIsConnected = false;



// initialize m_crypto here

}



CNetConn::~CNetConn()

{

}



BOOL CNetConn::CreateSocket(int iType, int iPort)

{

// iType == SOCK_DGRAM (UDP) | SOCK_STREAM (TCP)



struct sockaddr_in local;



m_socket = socket(AF_INET, iType, 0);

if (m_socket == INVALID_SOCKET)

{

WSACleanup();

DEBUGMSG("CNetConn::CreateSocket() couldn't create a socket");

return false;

}



if (iPort != 0)

{

local.sin_family = AF_INET;

local.sin_addr.s_addr = INADDR_ANY;

local.sin_port = htons(iPort);



if (bind(m_socket, (struct sockaddr*) &local, sizeof(local)) == SOCKET_ERROR)

{

WSACleanup();

DEBUGMSG("CNetConn::CreateSocket() couldn't bind socket");

return false;

}

}



return true;

}



BOOL CNetConn::Connect(CString strHost)

{

struct hostent *hp;

unsigned int addr;

unsigned short port = 0;

sockaddr_in to;

int retval;



if (strHost.IsEmpty()) return false;



port = atoi(strHost.Part(':', 1));

if (!port)

{

CString str;

str.Format("CNetConn::Connect() couldn't interpret port number \"%s\"", strHost.Part(':', 1));

DEBUGMSG(str);

return false;

}



if (isalpha(strHost[0])) /* server address is a name */

{

hp = gethostbyname(strHost.Part(':', 0));

}

else /* Convert nnn.nnn address to a usable one */

{

addr = inet_addr(strHost.Part(':', 0));

hp = gethostbyaddr((char *) &addr, 4, AF_INET);

}

if (hp == NULL)

{

CString str;

str.Format("CNetConn::Connect() can't resolve \"%s\"", strHost);

DEBUGMSG(str);

return false;

}



memset(&to, 0, sizeof(to));

memcpy(&(to.sin_addr), hp->h_addr, hp->h_length);

to.sin_family = hp->h_addrtype;

to.sin_port = htons(port);



retval = connect(m_socket, (sockaddr *) &to, sizeof(to));

if (retval == SOCKET_ERROR)

{

m_bIsConnected = false;

retval = WSAGetLastError();

CString str;

str.Format("CNetConn::Connect() can't connect(): error %d", retval);

DEBUGMSG(str);

return false;

}



m_bIsConnected = true;

return true;

}



void CNetConn::Close()

{

closesocket(m_socket);

m_socket = INVALID_SOCKET;

m_bIsConnected = false;

}



CNetConn CNetConn::GetConn()

{

sockaddr_in from;

int fromlen;

CNetConn conn;



fromlen = sizeof(from);



if (listen(m_socket, 5) == SOCKET_ERROR)

{

DEBUGMSG("CNetConn::GetConn() can't listen()");

}

else

{

conn.m_socket = accept(m_socket, (struct sockaddr*) &from, &fromlen);

conn.m_addr = from;

conn.m_strHost.Format("%s:%d", inet_ntoa(from.sin_addr), ntohs(from.sin_port));

}



//conn.SetEncryption(CRYPT_XOR);

m_bIsConnected = true;

return conn;

}



int CNetConn::Send(CString str)

{

return SendData(str.GetBuffer(), str.GetLength());

}



int CNetConn::SendData(LPVOID data, DWORD dwLength)

{

int retval;



CString strEnc;

memcpy(strEnc.GetBuffer(dwLength), data, dwLength);

strEnc.ReleaseBuffer(dwLength);

//strEnc = m_crypto.Encrypt(strEnc);



retval = send(m_socket, strEnc, dwLength, 0);

if (retval == SOCKET_ERROR)

{

retval = WSAGetLastError();

CString str;

str.Format("CNetConn::Connect() can't send(): error %d", retval);

DEBUGMSG(str);

return -1;

}



return retval;

}



int CNetConn::Recv(CString& str, int iMaxLen)

{

int retval;

int fromlen = 16;



retval = recv(m_socket, str.GetBuffer(iMaxLen), iMaxLen, 0);

if (retval < 0)

{

retval = WSAGetLastError();

if (retval = WSAECONNRESET)

{

str.ReleaseBuffer(0);

return 0;

}

CString str;

str.Format("CNetConn::Connect() can't recv(): error %d", retval);

DEBUGMSG(str);

return -1;

}

str.ReleaseBuffer(retval);



//str = m_crypto.Decrypt(str);



return retval;

}



BOOL CNetConn::IsValid()

{

return (m_socket != INVALID_SOCKET);

}



BOOL CNetConn::IsConnected()

{

return m_bIsConnected;

}



void WINAPI NetConnThread(LPVOID lParam)

{

NETNOTIFYPROC pNetNotify = (NETNOTIFYPROC) ((RECV_PARAM *) lParam)->pNetNotify;

CNetConn *conn = (CNetConn *) ((RECV_PARAM *) lParam)->conn;



free(lParam);



CString str;

int iRet;

bool bExitThread = false;



//DEBUGMSG("NetConnThread started");



pNetNotify(conn, str, NETNOTIFY_OPEN);

while (!bExitThread)

{

iRet = conn->Recv(str, 1000);

if (iRet > 0)

{

pNetNotify(conn, str, NETNOTIFY_DATA);

}

else if (iRet == 0)

{

str = "";

pNetNotify(conn, str, NETNOTIFY_CLOSE);

conn->Close();

bExitThread = true;

}

else

{

str = "";

pNetNotify(conn, str, NETNOTIFY_CLOSE);

conn->Close();

str.Format("NetConnThread can't recv(): error %d", iRet);

DEBUGMSG(str);

bExitThread = true;

}

}

app.m_iCurrConnCount--;



//DEBUGMSG("NetConnThread terminated");

}



HANDLE InitNetConnThread(CNetConn *conn, NETNOTIFYPROC *pNetNotify, DWORD *tid)

{

HANDLE hThread;

RECV_PARAM *prp = (RECV_PARAM *) malloc(sizeof(RECV_PARAM));

prp->pNetNotify = pNetNotify;

prp->conn = conn;



hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NetConnThread, prp, 0, tid);



if (!hThread)

return (HANDLE) 0;

else

{

app.m_iCurrConnCount++;

return hThread;

}

}



void WINAPI NetListenThread(LPVOID lParam)

{

NETNOTIFYPROC pNetNotify = (NETNOTIFYPROC) ((RECV_PARAM *) lParam)->pNetNotify;

CNetConn *listenconn = (CNetConn *) ((RECV_PARAM *) lParam)->conn;



free(lParam);



HANDLE hConnThread;

bool bExitThread = false;

DWORD dwTid;



//DEBUGMSG("NetListenThread started");



while (!bExitThread)

{

app.m_conn[app.m_iCurrConnCount] = listenconn->GetConn();

// TO-DO: also use free connections with lower index

if (app.m_iCurrConnCount >= MAX_CLIENT_CONN)

{

app.m_conn[app.m_iCurrConnCount].Close();

}

else

{

hConnThread = InitNetConnThread(&app.m_conn[app.m_iCurrConnCount], (NETNOTIFYPROC *) pNetNotify, &dwTid);

if (!hConnThread)

{

DEBUGMSG("NetListenThread can't InitNetConnThread(). quitting process");

ExitProcess(0);

}

}

}



//DEBUGMSG("NetListenThread terminated");

}



HANDLE InitNetListenThread(CNetConn *listenconn, NETNOTIFYPROC *pNetNotify, DWORD *tid)

{

HANDLE hThread;

RECV_PARAM *prp = (RECV_PARAM *) malloc(sizeof(RECV_PARAM));

prp->pNetNotify = pNetNotify;

prp->conn = listenconn;



hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) NetListenThread, prp, 0, tid);



if (!hThread)

return (HANDLE) 0;

else

return hThread;

}



int CNetConn::SetEncryption(int iMethod)

{

//return m_crypto.SetMethod(iMethod);

}