🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: borland.public.cppbuilder.nativeapi
6 messages
6 total messages Started by Martin Mon, 23 Apr 2007 14:34
Named Pipes problem
#2178
Author: Martin
Date: Mon, 23 Apr 2007 14:34
16 lines
1504 bytes
Using BCB 5 Pro, I'm trying to add named pipes to my app, and having 
some problems after the first client disconnects and shutdown. Basically 
what's happening is that the server is getting error 232 (pipe closing), 
233 (no process at other end of pipe), or 6 (invalid handle) when it's 
trying to use the pipe created for the second client.

I've tracked this down using the multi-threaded pipe server example from 
the MS SDK.  You can exhibit the problem if you change the CreateThread 
call to Borland's _beginthread, which they require to initialize the 
runtime libraries.

Has anyone tried getting named pipes to work in this model? How 
necessary is it to use _beginthread instead of CreateThread?

Thanks,
Marty
Re: Named Pipes problem
#2179
Author: Remy Lebeau (TeamB)
Date: Mon, 23 Apr 2007 18:15
23 lines
1689 bytes
"Martin" <dev@no.comppromed.spam.com> wrote in message
news:462cc3e6$1@newsgroups.borland.com...

> Using BCB 5 Pro, I'm trying to add named pipes to my app, and
> having some problems after the first client disconnects and shutdown
> Basically what's happening is that the server is getting error 232
> (pipe closing), 233 (no process at other end of pipe), or 6 (invalid
> handle) when it's trying to use the pipe created for the second
client.

Did you call DisconnectNamedPipe() after the first client
disconnected?  You can't reuse an existing server pipe unless you do.
This is stated in the documentation.

> Has anyone tried getting named pipes to work in this model? How
> necessary is it to use _beginthread instead of CreateThread?

It is not necessary at all.  I have plenty of named pipe code that
works just fine with CreateThread().


Gambit
Re: Named Pipes problem
#2180
Author: Martin
Date: Mon, 23 Apr 2007 19:34
38 lines
2450 bytes
Remy Lebeau (TeamB) wrote:
> "Martin" <dev@no.comppromed.spam.com> wrote in message
> news:462cc3e6$1@newsgroups.borland.com...
> 
>> Using BCB 5 Pro, I'm trying to add named pipes to my app, and
>> having some problems after the first client disconnects and shutdown
>> Basically what's happening is that the server is getting error 232
>> (pipe closing), 233 (no process at other end of pipe), or 6 (invalid
>> handle) when it's trying to use the pipe created for the second
> client.
> 
> Did you call DisconnectNamedPipe() after the first client
> disconnected?  You can't reuse an existing server pipe unless you do.
> This is stated in the documentation.
> 

Yes, DisconnectNamedPipe is being called.

>> Has anyone tried getting named pipes to work in this model? How
>> necessary is it to use _beginthread instead of CreateThread?
> 
> It is not necessary at all.  I have plenty of named pipe code that
> works just fine with CreateThread().
> 

Thanks. I tried using the TThread class and that seems to work fine as 
well.  Is it possibly something specific to BCB 5 that the Borland docs 
say _beginthread is required for the runtime libraries. The backend to 
these pipes are calling a lot of routines that use Borland's versions of 
the API calls instead of calling directly to Windows API. Bypassing 
_beginthread isn't going to cause any problems will it?

Thanks,
Marty
> 
> Gambit
> 
> 
Re: Named Pipes problem
#2181
Author: Remy Lebeau (TeamB)
Date: Mon, 23 Apr 2007 21:34
20 lines
1394 bytes
"Martin" <dev@no.comppromed.spam.com> wrote in message
news:462d0a59@newsgroups.borland.com...

> Yes, DisconnectNamedPipe is being called.

Then please show your actual code, and indicate where the error is
occuring.

> Is it possibly something specific to BCB 5 that the Borland docs
> say _beginthread is required for the runtime libraries.

I can't answer that.

> Bypassing _beginthread isn't going to cause any problems will it?

No.  TThread itself uses CreateThread().


Gambit
Re: Named Pipes problem
#2183
Author: Bob Gonder
Date: Tue, 24 Apr 2007 02:08
12 lines
1409 bytes
Martin wrote:

>Thanks. I tried using the TThread class and that seems to work fine as 
>well.  Is it possibly something specific to BCB 5 that the Borland docs 
>say _beginthread is required for the runtime libraries.

It is needed for the C runtime libraries (LIBCMT.LIB).
Apparently some of the functions can block and deadlock without the
_beginthread wakeup call.

The WinAPI doesn't apply.
The VCL probably doesn't care either.
Re: Named Pipes problem
#2189
Author: Martin
Date: Tue, 24 Apr 2007 15:08
174 lines
6439 bytes
Remy Lebeau (TeamB) wrote:
> "Martin" <dev@no.comppromed.spam.com> wrote in message
> news:462d0a59@newsgroups.borland.com...
> 
>> Yes, DisconnectNamedPipe is being called.
> 
> Then please show your actual code, and indicate where the error is
> occuring.
> 

As I said before, I can exhibit this problem using the server side of 
the multithreaded pipes example in the Microsoft SDK. Here is my 
modified example program.

Marty

//---------------------------------

#include <vcl.h>
#include <process.h>
#include <stdio.h>
#include <tchar.h>

#define BUFSIZE 4096

//DWORD WINAPI InstanceThread(LPVOID);
static void _USERENTRY InstanceThread( LPVOID);
VOID GetAnswerToRequest(LPTSTR, LPTSTR, LPDWORD);

#define THREAD_STACK    0

int _tmain(VOID)
{
    BOOL fConnected;
    DWORD dwThreadId;
    HANDLE hPipe, hThread;
    LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");

// The main loop creates an instance of the named pipe and
// then waits for a client to connect to it. When the client
// connects, a thread is created to handle communications
// with that client, and the loop is repeated.

    for (;;)
    {
       hPipe = CreateNamedPipe(
           lpszPipename,             // pipe name
           PIPE_ACCESS_DUPLEX,       // read/write access
           PIPE_TYPE_MESSAGE |       // message type pipe
           PIPE_READMODE_MESSAGE |   // message-read mode
           PIPE_WAIT,                // blocking mode
           PIPE_UNLIMITED_INSTANCES, // max. instances
           BUFSIZE,                  // output buffer size
           BUFSIZE,                  // input buffer size
           NMPWAIT_USE_DEFAULT_WAIT, // client time-out
           NULL);                    // default security attribute

       if (hPipe == INVALID_HANDLE_VALUE)
       {
           printf("CreatePipe failed");
           return 0;
       }
     else
         printf( "waiting for client connect to pipe %x\n", hPipe);

       // Wait for the client to connect; if it succeeds,
       // the function returns a nonzero value. If the function
       // returns zero, GetLastError returns ERROR_PIPE_CONNECTED.

       fConnected = ConnectNamedPipe(hPipe, NULL) ?
          TRUE : (GetLastError() == ERROR_PIPE_CONNECTED);

       if (fConnected)
       {
       // Create a thread for this client.
             hThread =(HANDLE) _beginthread( InstanceThread, 
THREAD_STACK, hPipe);

//         hThread = CreateThread(
//            NULL,              // no security attribute
//            0,                 // default stack size
//            InstanceThread,    // thread proc
//            (LPVOID) hPipe,    // thread parameter
//            0,                 // not suspended
//            &dwThreadId);      // returns thread ID

          if (hThread == NULL)
          {
             printf("CreateThread failed");
             return 0;
          }
          else
             {
             printf( "pipe %x passed to thread\n", hPipe);
             CloseHandle(hThread);
             }
        }
       else
         {
         printf( "client couldn't connect to pipe, closing %x\n", hPipe);
         // The client could not connect, so close the pipe.
          CloseHandle(hPipe);
         }
    }
}

//DWORD WINAPI InstanceThread(LPVOID lpvParam)
static void _USERENTRY InstanceThread(LPVOID lpvParam)
{
    TCHAR chRequest[BUFSIZE];
    TCHAR chReply[BUFSIZE];
    DWORD cbBytesRead, cbReplyBytes, cbWritten;
    BOOL fSuccess;
    HANDLE hPipe;

// The thread's parameter is a handle to a pipe instance.

    hPipe = (HANDLE) lpvParam;
    printf( "T%x, using pipe %x\n", GetCurrentThreadId(), hPipe);

    while (1)
    {
    // Read client requests from the pipe.
       fSuccess = ReadFile(
          hPipe,        // handle to pipe
          chRequest,    // buffer to receive data
          BUFSIZE*sizeof(TCHAR), // size of buffer
          &cbBytesRead, // number of bytes read
          NULL);        // not overlapped I/O

       DWORD err = GetLastError();
       if (! fSuccess || cbBytesRead == 0)
         {
         printf( "T%x, Error reading from pipe, err %d\n", 
GetCurrentThreadId(), err);
          break;
         }
       GetAnswerToRequest(chRequest, chReply, &cbReplyBytes);

    // Write the reply to the pipe.
       fSuccess = WriteFile(
          hPipe,        // handle to pipe
          chReply,      // buffer to write from
          cbReplyBytes, // number of bytes to write
          &cbWritten,   // number of bytes written
          NULL);        // not overlapped I/O

       err = GetLastError();
       if (! fSuccess || cbReplyBytes != cbWritten)
         {
         printf( "T%x error writing to pipe %x, success %d, wrote %d, 
err %d\n", GetCurrentThreadId(), fSuccess, cbWritten, err);
         break;
         }
   }

// Flush the pipe to allow the client to read the pipe's contents
// before disconnecting. Then disconnect the pipe, and close the
// handle to this pipe instance.

    FlushFileBuffers(hPipe);
    DisconnectNamedPipe(hPipe);
    CloseHandle(hPipe);

    return;
}

VOID GetAnswerToRequest(LPTSTR chRequest,
    LPTSTR chReply, LPDWORD pchBytes)
{
    _tprintf( TEXT("%s\n"), chRequest );
    lstrcpy( chReply, TEXT("Default answer from server") );
    *pchBytes = (lstrlen(chReply)+1)*sizeof(TCHAR);
}
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads