Recently I have completed the port-based project, I hope to test the most up to the most up to PRO. What should be known, when the customer connect to Server, CreateiocompletionPort calls the data of WSARECV Waiting for the client's initiative. Below is the test program, after a single client program is connected, the WSARECV is not stopped, and the size of the non-page buffer pool is observed, and it is found that the non-page buffer pool is more than 800 K, and the number of cycles is 2500, the program crashed. WSARECV calls to lock the specified page to physical memory, which will not be exchanged. . . My 2500 WSARECV locked more than 800 K. and there was no improvement in Data_bufSize to 8. So the program flew, it was ok, the system did not go crazy. Win2k is still relatively stable. Plus an operation of creating a Socket also requires a non-page buffer pool, and the client is estimated that the client connected to the actual single server is less than 2500. On the same Overlapped in a single Socket, if there is WSAARECV and WSasend, drink, that is, in WSARECV, WSARECV has received data before the end of WSASEND, if you do yourself when getqueuedCompletionStatus, is WSARECV or wsasend. This The situation is really difficult. I can't decide whether WSARECV returns or wsasend returns. So on the same Overlapped in a single socket, only one wsarecv or wsasend can have a WSARECV or WSasend. Before calling wsasend, it must be determined whether there is WSARECV. If there is, call Cancelio cancel, take up the page Exchange it. Of course, you can only call WSARECV, and use Send, Recv, etc., using Send, Recv, etc., if you receive the data. If there is a plurality of WSARECVs on a single socket, the page that is occupied will be locked until the WSARECV receives data or calls CANCLEIO, or the PostQueuedCompletionStatus or process is terminated. . . until. #include
Typedef struct {overlapped overlapped; car buffer [data_bufsize]; dword bytessend; dword bottesRecv;} per_io_operation_data, * lpper_io_operation_data;
Typedef struct {socket;} per_handle_data, * lpper_handle_data;
DWORD __STDCALL ServerWorkerthread (LPVOID CompletionPortid) {Return 0;
void main (void) {SOCKET Listen, Accept; HANDLE CompletionPort; LPPER_HANDLE_DATA PerHandleData; LPPER_IO_OPERATION_DATA PerIoData; DWORD RecvBytes, Flags; WSADATA wsaData; if ((WSAStartup (0x0202, & wsaData)) = 0!) {return;} if ((CompletionPort = CreateIoCompletionPort (INVALID_HANDLE_VALUE, NULL, 0, 0)) == NULL) {printf ( "CreateIoCompletionPort failed with error:% d / n", GetLastError ()); return;} if ((Listen = WSASocket (AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED) == IVALID_SOCKET) {Printf ("Wsasocket () failed with error% d / n", wsagetlasterror ()); return;} DWORD MEMORYSIZE = 256 * 1024 * 1024; Bool Result = FALSE DO {result = setProcessWorkingsetSize (getCurrentProcess (), memorysize, memorysize * 2); if (! Result) {memorySize - = 10 * 1024 * 1024;}}} while (! "); Printf (" MemorySize IS% DM / N ", MemorySize / 1024/1024); struct sockaddr_in stddr = {0}; int oddrlen = sizeof (struct sockaddr_in); STDDR.SIN_FAMILY = AF_INET; stddr.sin_addr.s_addr = htonl (inaddr_any); stddr.sin_port = HTONS (port);
IF (Bind (Listen, (PsockAddr) == SOCKET_ERROR) {Printf ("Bind () failed with error (" bind () failed with error% d / n ", wsagetlasterror (); return;} if (listen) 1) == SOCKET_ERROR) {Printf ("Listen () failed with error% d / n", wsagetlasterror ()); return;}
While (True) {IF ((Accept = WSAACcept (Listen, (SockAddr *) & stddr, & Iaddrlen, NULL, 0) == Socket_ERROR) {Printf ("WsaAccept () failed with error% d / n", wsagetlasterror () ); Return;} printf ("% s / n", inet_ntoa (stddr.sin_addr)); if (((prehangaData = (LPPER_HANDLE_DATA) Globalalloc (gptr, sizeof (per_handle_data)) == null) {printf ("GlobalAlloc Failed with error% d / n ", getLastError ()); return;" socket number% d connection / n ", accept; perhandata-> socket = accept; if (CreateiocompletionPort (Handle) Accept, CompletionPort , (DWORD) PerHandleData, 0) == NULL) {printf ( "CreateIoCompletionPort failed with error% d / n", GetLastError ()); return;} if ((PerIoData = (LPPER_IO_OPERATION_DATA) GlobalAlloc (GPTR, sizeof (PER_IO_OPERATION_DATA) )) == null) {Printf ("GlobalAlloc () Failed with Error% D / N", getLastError ()); return;}
ZeroMemory (& (PerIoData-> Overlapped), sizeof (OVERLAPPED)); PerIoData-> BytesSEND = 0; PerIoData-> BytesRECV = 0; PerIoData-> DataBuf.len = DATA_BUFSIZE; PerIoData-> DataBuf.buf = PerIoData-> Buffer ;
Flags = 0; int iLoop = 0; char chtemp [256] = {0}; while ( iLoop) {IF (WSarecv (ACCEPT, & (Periodata-> Database, 1, & Recvbytes, & Flags, & (PERIODATA- > Overlapped, null == SOCKET_ERROR) {IF (wsagetlasterror ()! = Error_io_pending) {printf ("wsarecv () failed with error% d / n", wsagetlasterror ()); return;}}