www.pudn.com > using IOCP.zip > client.h


 
// Written by Oz Ben Eliezer 
// o_be@hotmail.com 
// September, 2000 
 
#ifndef __CLIENT_H__		// Sentinels 
#define __CLIENT_H__ 
 
#define _WIN32_WINNT 0x0500 
 
#include  
#include  
 
#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