|
// Written by Oz Ben Eliezer
// o_be@hotmail.com
// September, 2000
#ifndef __CLIENT_H__ // Sentinels
#define __CLIENT_H__
#define _WIN32_WINNT 0x0500
#include <windows.h>
#include <time.h>
#include "buffer.h"
#include "general.h"
#include "callback.h"
#define IN_BUFFER_SIZE 2048
#define IN_BUFFER_SIZE_INC 2048
#define MAX_IN_BUFFER_SIZE 1048576
#define OUT_BUF_SIZE 4096
#define STATE_DEAD 0
#define STATE_ACCEPTING 1
#define STATE_CONNECTED 2
struct OVERLAPPED_PLUS : public OVERLAPPED
{
unsigned int client;
bool bCtxWrite;
};
class CClient
{
protected:
CAutoBuffer *out_buffer; // Data that is to be sent to client
unsigned long nWritten;
char *actual_in_buf;
char *actual_out_buf;
OVERLAPPED_PLUS ovIn; // Used in WSARead() calls
OVERLAPPED_PLUS ovOut; // Used in WSASend() calls
char *end_in_buf_pos;
char *start_in_buf_pos;
CRITICAL_SECTION csInUse;
sockaddr_in local;
sockaddr_in peer;
int nInBufferSize;
tagPacket *p; // Packet for processing
time_t ltime;
__forceinline void InitializeInUse()
{
InitializeCriticalSection(&csInUse);
}
__forceinline void DeleteInUse()
{
DeleteCriticalSection(&csInUse);
}
__forceinline void Timestamp()
{
time(<ime);
}
__forceinline int SecondsElapsed()
{
time_t timenow;
time(&timenow);
return timenow - ltime;
}
public:
static int nID;
int nSpecificID;
__forceinline void EnterInUse()
{
EnterCriticalSection(&csInUse);
}
__forceinline void LeaveInUse()
{
LeaveCriticalSection(&csInUse);
}
SOCKET s; // Socket used to communicate with client
int nState; // Current state of instance
long bPendingWrite; // Is there data pending to be sent?
long bMayWrite; // Is it possible to send data now?
unsigned long nRead;
CClient();
~CClient();
void Init(); // Attach to a new client
void Close(); // Detach from a client
bool Write(tagPacket *p); // Add a packet to output buffer
bool Read(tagPacket *p); // Retrieve a packet from input buffer
bool NetWrite(); // Do actual send
bool IssueNetRead(); // Do actual receive
void SetRead(int nNewlyRead);
__forceinline void ShiftState() // Move from ACCEPTING to CONNECTED state
{
int locallen, remotelen;
sockaddr_in *plocal = 0, *premote = 0;
if (nState == STATE_ACCEPTING)
{
GetAcceptExSockaddrs(&actual_in_buf[0],
IN_BUFFER_SIZE,
sizeof(sockaddr_in) + 16,
sizeof(sockaddr_in) + 16,
(sockaddr **)&plocal,
&locallen,
(sockaddr **)&premote,
&remotelen);
memcpy(&local, plocal, sizeof(sockaddr_in));
memcpy(&peer, premote, sizeof(sockaddr_in));
if (BindIoCompletionCallback((HANDLE)s, DoneIO, 0))
{
nState = STATE_CONNECTED;
Timestamp();
printf("\nConnected client, ID# %d", nSpecificID);
}
}
}
__forceinline bool Read()
{
return Read(p);
}
__forceinline int ProcessPacket()
{
return ProcessPacket(p);
}
virtual int ProcessPacket(tagPacket *p) = 0; // Process a packet.
virtual void CreateInvalidPacket(tagPacket *p) = 0; // Invalidate packet.
virtual void Maintenance() = 0; // Maintenance
};
#endif
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.