Thread View: borland.public.cppbuilder.nativeapi
6 messages
6 total messages
Started by Martin
Mon, 23 Apr 2007 14:34
Named Pipes problem
Author: Martin
Date: Mon, 23 Apr 2007 14:34
Date: Mon, 23 Apr 2007 14:34
16 lines
1504 bytes
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
Author: Remy Lebeau (TeamB)
Date: Mon, 23 Apr 2007 18:15
Date: Mon, 23 Apr 2007 18:15
23 lines
1689 bytes
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
Author: Martin
Date: Mon, 23 Apr 2007 19:34
Date: Mon, 23 Apr 2007 19:34
38 lines
2450 bytes
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
Author: Remy Lebeau (TeamB)
Date: Mon, 23 Apr 2007 21:34
Date: Mon, 23 Apr 2007 21:34
20 lines
1394 bytes
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
Author: Bob Gonder
Date: Tue, 24 Apr 2007 02:08
Date: Tue, 24 Apr 2007 02:08
12 lines
1409 bytes
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
Author: Martin
Date: Tue, 24 Apr 2007 15:08
Date: Tue, 24 Apr 2007 15:08
174 lines
6439 bytes
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