 |
BorlandTalk.com Borland discussion newsgroups
|
| View previous topic :: View next topic |
| Author |
Message |
Martin Guest
|
Posted: Mon Apr 23, 2007 7:34 pm Post subject: Named Pipes problem |
|
|
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 |
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Mon Apr 23, 2007 11:15 pm Post subject: Re: Named Pipes problem |
|
|
"Martin" <dev (AT) no (DOT) comppromed.spam.com> wrote in message
news:462cc3e6$1 (AT) newsgroups (DOT) borland.com...
| Quote: | 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.
| Quote: | 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 |
|
| Back to top |
|
 |
Martin Guest
|
Posted: Tue Apr 24, 2007 12:34 am Post subject: Re: Named Pipes problem |
|
|
Remy Lebeau (TeamB) wrote:
| Quote: | "Martin" <dev (AT) no (DOT) comppromed.spam.com> wrote in message
news:462cc3e6$1 (AT) newsgroups (DOT) 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.
| Quote: | 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
|
|
| Back to top |
|
 |
Remy Lebeau (TeamB) Guest
|
Posted: Tue Apr 24, 2007 2:34 am Post subject: Re: Named Pipes problem |
|
|
"Martin" <dev (AT) no (DOT) comppromed.spam.com> wrote in message
news:462d0a59 (AT) newsgroups (DOT) borland.com...
| Quote: | Yes, DisconnectNamedPipe is being called.
|
Then please show your actual code, and indicate where the error is
occuring.
| Quote: | 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.
| Quote: | Bypassing _beginthread isn't going to cause any problems will it?
|
No. TThread itself uses CreateThread().
Gambit |
|
| Back to top |
|
 |
Bob Gonder Guest
|
Posted: Tue Apr 24, 2007 7:08 am Post subject: Re: Named Pipes problem |
|
|
Martin wrote:
| Quote: | 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. |
|
| Back to top |
|
 |
Martin Guest
|
Posted: Tue Apr 24, 2007 8:08 pm Post subject: Re: Named Pipes problem |
|
|
Remy Lebeau (TeamB) wrote:
| Quote: | "Martin" <dev (AT) no (DOT) comppromed.spam.com> wrote in message
news:462d0a59 (AT) newsgroups (DOT) 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);
} |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|