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