![]() |
Named Pipe hangs
I am trying to write client and server programs that communicate with
named pipes. There is one multithreaded server that handles all of the requests and multiple multithread clients that make the requests. The problem is that the client hangs at the WriteFile request when running under load. All the processes are running on the same box. I am wondering if there is something I am doing wrong fundamentally. One thing I am doing that is questionable is opening the pipe on the server side in Overlapped mode and but not using overlapped mode on the client side. I don't know if this would cause any problems since they are on the same box. If I change the server to open the pipe with a inital pipebuffer of 120 for read and write buffers the client then hangs at the readfile(). Any ideas? SERVER MAIN: ---------------------- HANDLE hPipe = INVALID_HANDLE_VALUE; HANDLE hEvents[2] = {NULL, NULL}; HANDLE hServerStopEvent = CreateEvent(NULL,TRUE,FALSE,NULL); hEvents[0] = hServerStopEvent; while (1) { OVERLAPPED *pOS = NULL; hEvents[1] = CreateEvent( NULL, // no security attributes TRUE, // manual reset event FALSE, // not-signalled NULL); // no name // Create the pipe hPipe = CreateNamedPipe( szPipeName, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES, 0, 0, NMPWAIT_USE_DEFAULT_WAIT, &sa); // security attributes pOS = (OVERLAPPED *) calloc (1, sizeof(OVERLAPPED) ); pOS->hEvent = hEvents[1]; ResetEvent( hEvents[1] ); // wait for a connection... bool bError = false; bConnected = ConnectNamedPipe(hPipe, pOS); if (!bConnected) { if (GetLastError() == ERROR_IO_PENDING) { // Wait for the data to be ready DWORD dwWait = WaitForMultipleObjects( 2, hEvents, FALSE, INFINITE ); if ( dwWait != WAIT_OBJECT_0+1 ) break; // Server stop or error } else bError=true; } if (!bError) { //Create a thread to handle the request CloseHandle(pOS->hEvent); free(pOS); } } SERVER WORKER THREAD: ---------------------- // create a Overlapped structure for read OVERLAPPED *pOS = NULL; HANDLE hOS = INVALID_HANDLE_VALUE; // init the overlapped structure hOS = CreateEvent(NULL,TRUE,FALSE,NULL); pOS = (OVERLAPPED *) calloc (1, sizeof(OVERLAPPED) ); pOS->hEvent = hOS; ResetEvent( hOS ); // Get the size of the message PeekNamedPipe(hPipe,NULL,0,NULL,&dwTotalBytesAvail ,&dwBytesLeftInMessage); // create a buffer based on the size from peek bResult = ReadFile( hPipe,szBuffer,dwTotalBytesAvail,&dwBytesRead,pOS) ; if ( !bResult ) { if (ERROR_IO_PENDING == GetLastError()) { DWORD dwNumBytesTransferred = 0; // The data is not ready yet, wait for the operation to be complete GetOverlappedResult(hPipe,pOS, &dwNumBytesTransferred,true); ResetEvent(pOS->hEvent); } } CloseHandle(pOS->hEvent); free(pOS); pOS=NULL; // Do stuff with the message and create a response // create a Overlapped structure for write *pOS = NULL; hOS = INVALID_HANDLE_VALUE; // init the overlapped structure hOS = CreateEvent(NULL,TRUE,FALSE,NULL); pOS = (OVERLAPPED *) calloc (1, sizeof(OVERLAPPED) ); pOS->hEvent = hOS; ResetEvent( hOS ); // Send the response bResult = WriteFile( this->hPipe, szOutMsg, iOutMsgSize, &dwBytesWritten, pOverlapped); if (!bResult) { int iWriteFileError = GetLastError(); if (ERROR_IO_PENDING == iWriteFileError) { DWORD dwNumBytesTransferred = 0; // The data is not ready yet, wait for the operation to be complete GetOverlappedResult(hPipe,pOverlapped,&dwNumBytesT ransferred,true); ResetEvent(pOS->hEvent); bResult = true; } } CloseHandle(pOS->hEvent); free(pOS); pOS=NULL; // Clean up FlushFileBuffers(hPipe); DisconnectNamedPipe(hPipe); CloseHandle( hPipe ); ---------------------- CLIENT THREAD: DWORD dwPipeMode = PIPE_READMODE_MESSAGE; hPipe = CreateFile( szPipeName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL ); if (hPipe == INVALID_HANDLE_VALUE) WaitNamedPipe(szPipeName, 20000); // Then try again (not shown here) SetNamedPipeHandleState( this->hPipe, &dwPipeMode,NULL, NULL ); // Write the message bResult = WriteFile( this->hPipe, szOutMsg, iOutMsgSize, &dwBytesWritten, NULL); // Read the answer bResult = PeekNamedPipe (hPipe,NULL,0,NULL,&dwTotalBytesAvail,&dwBytesLeft InMessage); if (dwTotalBytesAvail == 0) { // We don't know how big to make the buffer so default to 120 // since that is bigger than twice the size of // most messages in testing. dwTotalBytesAvail = 120; } ReadFile( hPipe, // file to read from szBuffer, // address of input buffer dwTotalBytesAvail, // number of bytes to read &dwBytesRead, // number of bytes read NULL); // not overlapped CloseHandle( hPipe ); |
Re: Named Pipe hangs
AckMike@gmail.com wrote:
> I am trying to write client and server programs that communicate with > named pipes. There is one multithreaded server that handles all of the > > requests and multiple multithread clients that make the requests. The > problem is that the client hangs at the WriteFile request when running > under load. All the processes are running on the same box. I am > wondering if there is something I am doing wrong fundamentally. > > One thing I am doing that is questionable is opening the pipe on the > server side in Overlapped mode and but not using overlapped mode on the > > client side. I don't know if this would cause any problems since they > are on the same box. > > If I change the server to open the pipe with a inital pipebuffer of 120 > > for read and write buffers the client then hangs at the readfile(). > Any ideas? > This is a better question for a OS newsgroup. Something in the area of linux, unix, or posix. There are no "pipes" as defined by Standard C++. See http://www.parashift.com/c++-faq-lite/ for more information about comp.lang.c++. --John Ratliff |
| All times are GMT. The time now is 07:36 AM. |
Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.