First, run the program
Development environment MDAC2.7, VC6 SP5, WIN2000
If your MDAC version is the old upgrade or recompile. Server-side database Access, operate with ADO. The client's file system is used in CSV format. Place the SMSServer and SMSClient on the same machine because I set IP to 127.0.0.1, SMSServerDB and SMSServer were placed in the same directory. The source code is compiled by 1 bytes, and the program is not tested under the condition of the network burden and the number of Socket connections.
Second, data structure and communication protocols and processing implementations
The server side is completed with completion port asynchronous mode, and the client is implemented by the synchronous Socket class.
The server side has a listening thread and the working thread consists.
TypedEf struct _ssionpack {word commandid; // command idword datalength; // data data length Word DataItems; // data area data item number, number of effective structures in DATA CHAR DATA [1]; // Data Zone} Sessionpack, * psessionpack;
The first three fields are equivalent to the header, and DATA is the active data first address. Assign it as needed. Structural definition
In the packet.h file, the protocol is defined in the protocol.h file. A sessionpack should not exceed 4K. CiocpFrame is a package class that completes the port, and the business logic is handled in CiocpFrame :: ProecssJob, where several database operations are functioning in Server.h. PER_HANDLE_DATA, PER_IO_OPERATION_DATA These two structures are detailed, please see the completed port.
The client sends a large amount of data processing, for example, upload contact
For (int J = 0; j File: // Next data PDATA ;} g_pclient-> send (PPACK, SIZEOF (SESSIONPACK) SIZEOF (LINK) * MAXLINK-1, 0); delete ppack;} // ifj else // The last group may not be MaxLink LINK Structures {Int Ileft = Parser.m_nRows-J * MaxLink; PsessionPack PPack = (PsessionPack) New Char [SIZEOF (SESSIONPACK) SIZEOF (LINK) * ILEFT-1]; PLINK PDATA = (PLINK) PPACK-> Data; MEMSET (PPACK, 0, SIZEOF (SESSIONPACK) SIZEOF (LINK) * ILEFT-1); PPACK-> DATALENGTH = SIZEOF (LINK) * ILEFT; PPACK-> DataItems = Ileft; PPACK-> CommandId = Command_upload_link; (INT i = 0; I // server accepts data PLINK PBODY; PBODY = (PLINK) PPACK-> DATA; For (INT i = 0; i The server sends a large amount of data to the client such as the download address book. The principle is similar to a large number of clients, but when the server sends a large last package, set the command word to command_download_link_exit to inform the client data transmission, please do not receive it. When the client requests, you need to store the maximum ID of the local data in the valid data area to tell the server to avoid repeating the query. Third, complete the port introduction Mainly used 3 functions and an overlapped structure Whenever there is a connection, it is associated with the completed port. The completion port is actually a queue of overlapping IO. When an object in the queue has a signal, getQueuedCompletionStatus returns, and the overlapping IO and corresponding The document handle data is transmitted, and this single handle data in my program is the client sleeve, then you can operate the buffer data. HANDLE CreateIoCompletionPort (HANDLE FileHandle, // handle HANDLE ExistingCompletionPort for complete device ports, // handle to complete the port, if it is NULL then generate a new ULONG_PTR CompletionKey, // handle document data DWORD NumberOfConcurrentThreads // maximum allowed worker threads Number; // The main function of this function is to generate a completion port, or associate a handle and completed port to Bool getQueuedCompletionStatus (Handle CompletionPort, // Required to monitor the completed port handle LPDWORD LPNUMBEROFBYTES, / / Real Transfer byte Pulong_ptr LPCompletionKey , // single handle data LPOVERLAPPED * LPOVERLAPPED, // A pointer to the forged overlap IO, depends on your definition DWORD dwmilliseconds // waiting for how many seconds); This function returns a few possibilities, and a overlapping IO has transmitted data transmission, or the client closeSocket, or other reasons, resulting in completion port failed, or the server calls PostQueuedCompletionStatus proactive requirements end. The following is the judgment code I am in the program. Bsuccess = getQueuedCompletionStatus (g_hcompport, & dwnumbytes, (dword *) & perhandaData, (overlapped **) & context, infinite; if (! bSuccess) {file: // client disconnects if (PerHandleData = NULL!) if (dwNumBytes == 0 && PerHandleData-> pIOContext-> OperationType == RECV_POST) {pIocpFrame-> CloseClient (PerHandleData); continue;} } IF (BSuccess) if (Perhandata == Null && DwnumBytes == 0) {file: // Working thread is notified to end set set set (g_threadhandles [pos]); return 0;} Bool PostQueuedCompletionStatus (Handle Completionport, DWORD DWNUMBEROFBYTESTRANSFERRED, ULONG_PTR DWCOMMPMOMPMOMPLETYKEY, LPOVERLAPPED LPOVERLAPPED); I use this function to tell me to stop working. You can also send other word definition messages to complete ports in this function, but call this function to remember to close all clients first. In the program, my client socket is saved in the list is a few functions starting by the CTX. Fourth, conclude The program is a summary I learned to complete the port, and the source code variable function structure is less than that may be less than reading. Using the Complete Port Design Process is the understanding of several functions of the completion port. Mainly used for file upload download services. The gateway, C / S can also be used, and the defect cannot be ported to the UNIX platform. Reference: Example of IOCP in PlatformSDK, MSDN, Windows Network Program Design Client EXE server EXE server database original code my home page