名前付きパイプサーバーとクライアントがあります。 (これをVC++で行う)。名前付きパイプに再接続する際の問題
サーバし
- CreateNamedPipe
- ConnectNamedPipe
- のWriteFile
- 切断
- 2からクリエ
4を繰り返しNTはありません
- のCreateFile
- のReadFile
、
- サーバ - CreateNamedPipe
- クライアント - のCreateFile
- サーバ - - ConnectNamedPipe(すぐにclとして返す必要がありますientはすでに)
- サーバー接続されている - のWriteFileを
- クライアント - のReadFile
- サーバ - DisconnectNamedPipe
- クライアント - CloseHandleを
- 後藤2
これは最初のために正常に動作します時間。ただし、クライアントが2回目の接続を試みると問題が発生します。クライアントがの前にの前に接続(CreateFile)しようとすると、サーバーはConnectNamedPipeを実行しましたが(のdisconnectnamedpipeの後に)、ERROR_PIPE_BUSYを取得します。サーバーがConnectNamedPipeを呼び出した後、クライアントがcreatefileを呼び出すと機能します。
(DisconnectNamedPipeの後に)ConnectNamedPipeという名前のサーバーの前にクライアントを接続する(CreateFile)ことができますか?
Serverコード:
pipe_handle.pipe = CreateNamedPipe(TEXT("\\\\.\\pipe\\testpipe1"),
PIPE_ACCESS_OUTBOUND |
FILE_FLAG_OVERLAPPED, // read/write access
PIPE_TYPE_MESSAGE | // message type pipe
PIPE_READMODE_MESSAGE | // message-read mode
PIPE_WAIT, // blocking mode
PIPE_UNLIMITED_INSTANCES, // max. instances
BUFFER_SIZE, // output buffer size
BUFFER_SIZE, // input buffer size
2000, // client time-out
NULL);
if (pipe_handle.pipe == INVALID_HANDLE_VALUE) {
std::cout << "Error while creating pipe" << std::endl;
return -1;
}
std::cout <<"Connecting to named pipe" << std::endl;
std::cout<< "Somebody connected to named pipe" << std::endl;
int ac;
for (ac=0; ac<2; ac++) {
char a[25];
// Wait for some input. This helps me to start the client in other terminal.
cin >> a;
cout << "Connecting..." << endl;
ConnectNamedPipe(pipe_handle.pipe, 0);
cout << "Connect pipe returned." << endl;
// Wait for some input.
cin >> a;
string message = "Test message";
DWORD bytes_written;
if (!WriteFile(pipe_handle.pipe, message.c_str(), message.size(),
&bytes_written, NULL)) {
DWORD er = GetLastError();
char errs[200];
sprintf(errs, "Error : %ld", er);
std::cout << "Error communicating to client.";
std::cout << errs;
}
std::cout << "Written to pipe";
FlushFileBuffers(pipe_handle.pipe);
if (!DisconnectNamedPipe(pipe_handle.pipe)) {
std::cout << "Disconnect failed"<< GetLastError() << endl;
} else {
std::cout << "Disconnect successful"<<endl;
}
}
クライアントコード:あなたは、クライアントでのCreateFile()の呼び出しにERROR_PIPE_BUSYを取得する場合
while (1) {
std::cout << "Returned" << std::endl;
hPipe = CreateFile(
lpszPipename, // pipe name
GENERIC_READ,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
FILE_FLAG_OVERLAPPED, // default attributes
NULL); // no template file
// Break if the pipe handle is valid.
if (hPipe != INVALID_HANDLE_VALUE)
break;
// Exit if an error other than ERROR_PIPE_BUSY occurs.
if (GetLastError() != ERROR_PIPE_BUSY) {
std::cout<< "Could not open pipe " << GetLastError() << std::endl;
return -1;
}
// All pipe instances are busy, so wait for sometime.
if (! WaitNamedPipe(lpszPipename, NMPWAIT_USE_DEFAULT_WAIT)) {
std::cout<< "Could not open pipe: wait timed out." << std::endl;
}
}
OVERLAPPED ol1;
memset(&ol1, 0, sizeof(ol1));
ol1.Offset = 0;
ol1.OffsetHigh = 0;
ol1.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
HANDLE events[1];
events[0] = ol1.hEvent;
cbToWrite = (lstrlen(message)+1)*sizeof(TCHAR);
DWORD bytes_to_read = 2000;
char * buf = reinterpret_cast<char *>(malloc(bytes_to_read));
DWORD bytes_read;
std::cout << "Waiting for read" << std::endl;
bool a = ReadFile(hPipe, buf, bytes_to_read, &bytes_read, &ol1);
if (! fSuccess) {
std::cout << "WriteFile to pipe failed. GLE " << GetLastError() << std::endl;
}
std::cout << "Waiting for multiple objects" << std::endl;
WaitForMultipleObjects(1, events, FALSE, INFINITE);
std::cout << "multiple objects returned" << std::endl;
printf("\nMessage sent to server");
CancelIo(hPipe);
CloseHandle(hPipe);
返信いただきありがとうございます。このコードで試しましたが、クライアントはERROR_PIPE_BUSYを取得し続けます。サーバーがConnectNamedPipe()を呼び出すと、クライアントはエラーなくCreateFile()を正常に実行できます。 – Ashwin
質問をサーバーとクライアントのコード – Ashwin
に更新しました@Ashwin:編集する編集を参照してください。 –