In-Depth Network Programming in C++
In-Depth Network Programming in C++
In-Depth Network Programming in C++
com/Tips/5345359/In-Depth-Network-Programming-in-Cplusplus
Introduction
In this article, we introduce the basic primitives used to work with sockets, which are defined in winsock2.h file
for the version 2.0.
We will also present the two useful utility programs which solve various networking tasks.
Of course, we could use Microsoft Foundation Classes (MFC) for asynchronous programming, however, our
approach is more optimal for system network programming.
Thus, CPing program presented in this article is a utility which pings user-defined protocols and measures the
speed of connection.
Another example like CSocks presents the tunneling algorithm for proxying on SOCKS-5 protocol for
messengers like Internet Relay Chat (IRC).
Background
The article is to be studied according to the Request For Comment (RFC) standard for CSocks project as it uses
the command order for SOCKS-4/5 internet TCP protocol and, thus, operates on user or higher level, rather,
than same "ping" utility which operates on system level and protocol like Internet Control Message Protocol
(ICMP).
Thus, we introduce the same ping utility in CPing project, which works as is in order to test
functionality of HyperText Transfer Protocol (HTTP) and others that operate on the user-defined level.
C++
#include <windows.h>
#include <winsock2.h> // necessary
#include "CPing.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
CPing::CPing()
{
iTimeOut = 1000;
iBytesToRecv = 0;
iLastError = WSAStartup (MAKEWORD(2,0),&wsadata); // initialize Windows Sockets
strcpy (szNoop, NOOP);
}
CPing::~CPing()
{
WSACleanup(); // clean up the Windows Sockets cache
}
C++
Shrink ▲
#ifndef __CPING_CLASS
#define __CPING_CLASS
typedef struct {
unsigned int iTimeSend; // measured time to send TCP packet
unsigned int iTimeRecv; // measured time to receive TCP packet
unsigned int iTotalSent, iTotalRecvd; // total number of bytes sent and received
unsigned int iPort; // TCP protocol port
} pingstore;
class CPing
{
public:
CPing();
~CPing();
char szNoop[256];
int iLastError, iTotalRes, iBytesToRecv;
unsigned int iTimeOut, iTotalSent, iTotalRecvd;
unsigned int PingContinuous
(char* szHost, unsigned int iPort, unsigned int iPackets);
unsigned int PingConnective
(char* szHost, unsigned int iPort, unsigned int iPackets);
pingstore* Res;
private:
WSADATA wsadata;
};
#endif
To be clear enough, we have to present an example of the usage of object-oriented programming
with the support of windows sockets in the CPing utility as follows:
C++
Shrink ▲
unsigned int CPing::PingContinuous
(char* szHost, unsigned int iPort, unsigned int iPackets)
{
struct hostent* host = NULL;
struct sockaddr_in saddr;
unsigned int s = 0;
unsigned int dw1, dw2, dw3;
char szBuffer[256];
Another example like CSocks network utility for proxying on SOCKS-5 protocol is defined as follows:
C++
Shrink ▲
#ifndef __CSOCKS_HEADER
#define __CSOCKS_HEADER
#include "common.h"
#include "cauth.h"
class CSocks {
private:
public:
PSOCKSNOTIFYPROC pNotifyProc;
u_short uPort, mode;
u_int uAccept;
u_long LastError;
CSocksBasicAuth* basicauth = NULL;
CSocks() {
uAccept = 0;
mode = SOCKS_MODE_TCP;
uPort = SOCKS_DEF_PORT;
LastError = SOCKS_ERROR_NONE;
pNotifyProc = NULL;
};
~CSocks() {
if(uAccept) closesock(uAccept);
};
#endif
We present this class for the example realization of the network operation like tunneling when the
network data are passed through the mediate socket - this concept primarily is used in proxy
software, this operation is defined as follows ( sres and sdest are sockets between which the
tunneling operation performs):
C++
Shrink ▲
bool CSocks::SocksTCPTunneling(u_int sres, u_int sdest)
{
register u_int sockr, sockw, ret;
register u_int uread, uwrote;
char szBuffer[1024];
struct fd_set fd;
struct timeval tv = {0,0};
do
{
FD_ZERO(&fd);
FD_SET(sres,&fd);
FD_SET(sdest,&fd);
uread = recv(sockr,szBuffer,1023,0);
szBuffer[uread] = 0;
uwrote = 0;
if(!VALID_SOCKET(uread) || uread==0) break;
while(uwrote<uread)
{
ret = send(sockw,szBuffer+uwrote,uread-uwrote,0);
if(!VALID_SOCKET(ret)) goto __quit;
uwrote += ret;
}
}
FD_ZERO(&fd);
FD_SET(sres,&fd);
FD_SET(sdest,&fd);
if(select(0,NULL,NULL,&fd,&tv)>0) break;
} while(1);
__quit:
return(true);
}
That's all for now, other minor procedures and functions can be studied from our repositories,
however, all the above represent the necessary knowledge in order to work with sockets on system
level in C++ programming language.
Points of Interest
Thus, we have learned how to adopt sockets layer model for particular network tasks for better
performance and more deep functionality and assessment.