问题重复为命名频道

我有一个命名频道的服务器和客户端。 /这样做 VC++/.

服务器

可以

CreateNamedPipe

ConnectNamedPipe

WriteFile

断开

重复 2 到 4

客户

做。

CreateFile

ReadFile

执行顺序如下

服务器 -- CreateNamedPipe

客户 -- CreateFile

服务器 -- ConnectNamedPipe /必须立即返回,因为客户已连接/

服务器 -- WriteFile

客户 -- ReadFile

服务器 -- DisconnectNamedPipe

客户 - CloseHandle

去 2

它是第一次工作。 但是,当客户端尝试第二次连接时,会出现问题。 当客户试图连接时 /CreateFile/ 第二次



服务器如何完成 ConnectNamedPipe /但



disconnectnamedpipe/, 他收到了 ERROR_PIPE_BUSY. 如果客户原因,它有效 createfile 服务器发生后 ConnectNamedPipe.

无论如何,我可以连接客户端 /CreateFile/ 在服务器原因之前 ConnectNamedPipe /后 DisconnectNamedPipe/?

服务器代码:


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; !="" "="" "could="" "returned"="" &ol1,="" *="" -1;="" 0,="" 1="" ;="" <<="" [code]while="" all="" an="" are="" attributes="" break="" break;="" buf="reinterpret_cast&lt;char" busy,="" bytes_to_read="2000;" cbtowrite="/lstrlen/message/+1/*sizeof/TCHAR/;" char="" code]="" default="" dword="" error="" error_pipe_busy="" events[0]="ol1.hEvent;" events[1];="" existing="" exit="" false,="" file="" file_flag_overlapped,="" for="" generic_read,="" getlasterror="" handle="" hpipe="" if="" instances="" is="" lpszpipename,="" memset="" name="" nmpwait_use_default_wait="" no="" not="" null="" null,="" occurs.="" ol1="" ol1.hevent="CreateEvent/NULL," ol1.offset="0;" ol1.offsethigh="0;" ol1;="" open="" open_existing,="" opens="" other="" out."="" overlapped="" pipe="" pipe:="" return="" security="" sharing="" sizeof="" so="" sometime.="" std::cout="" std::cout<<="" std::endl;="" template="" than="" the="" timed="" true,="" valid.="" wait="" waitnamedpipe="" {="" }="" }[="" 客户代码:="">/malloc/bytes_to_read//;
DWORD bytes_read;

std::cout &lt;&lt; "Waiting for read" &lt;&lt; std::endl;
bool a = ReadFile/hPipe, buf, bytes_to_read, &amp;bytes_read, &amp;ol1/;


if / ! fSuccess/ {
std::cout &lt;&lt; "WriteFile to pipe failed. GLE " &lt;&lt; GetLastError// &lt;&lt; std::endl;
}
std::cout &lt;&lt; "Waiting for multiple objects" &lt;&lt; std::endl;
WaitForMultipleObjects/1, events, FALSE, INFINITE/;
std::cout &lt;&lt; "multiple objects returned" &lt;&lt; std::endl;
printf/"\nMessage sent to server"/;
CancelIo/hPipe/;
CloseHandle/hPipe/;


</endl;>
已邀请:

三叔

赞同来自:

如果你得到 ERROR_PIPE_BUSY 在呼唤时 CreateFile// 在客户端,您需要打电话 WaitNamedPipe//, 然后在返回时重复尝试。 如果你得到零返回 WaitNamedPipe//, 这意味着等待时间已过期,而不成为管道实惠。 如果你通过,你永远不会看到它发生了什么 nmpwait_wait_forever 超时。

您还应该记住,管道可以再次变得忙碌之间 WaitNamedPipe// 和挑战 CreateFile//; 因此,您需要在循环中执行此操作。 类似于这个:


while /true/
{
hPipe = CreateFile/pipeName,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
0/;
if /hPipe == INVALID_HANDLE_VALUE/
{
if /GetLastError// == ERROR_PIPE_BUSY/
{
if /!WaitNamedPipe/pipeName, NMPWAIT_USE_DEFAULT_WAIT//
continue; // timeout, try again
}
else
return false; // error
}
else
break; // success
}


EDIT:

我简化了你的代码,现在它正常工作。 服务器和客户工作。

服务器

:


#include <windows.h>
#include <stdio.h>

int main/void/
{
HANDLE pipe;
const DWORD BUFFER_SIZE = 1024;

pipe = CreateNamedPipe/"\\\\.\\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 == INVALID_HANDLE_VALUE/
{
printf/"Error while creating pipe\n"/;
return -1;
}
printf/"Connecting to named pipe\n"/;

int ac;

for /ac=0; ac&lt;2; ac++/
{
// Wait for some input. This helps me to start the client in other terminal.
printf/"Connecting...\n"/;

ConnectNamedPipe/pipe, 0/;

printf/"Connect pipe returned.\n"/;

// Wait for some input.
char * message = "Test message";
DWORD bytes_written;

if /!WriteFile/pipe, message, strlen/message/+1, &amp;bytes_written, NULL//
{

DWORD er = GetLastError//;
char errs[200];
sprintf_s/errs, "Error : %ld", er/;
printf/"Error communicating to client.\n"/;
printf/errs/;
}
printf/"Written to pipe\n"/;
FlushFileBuffers/pipe/;
if /!DisconnectNamedPipe/pipe//
{
printf/"Disconnect failed %d\n", GetLastError///;
}
else
{
printf/"Disconnect successful\n"/;
}
}
}


客户

:


#include <windows.h>
#include <stdio.h>

int main/void/
{
HANDLE hPipe;

while /1/
{

printf/"Returned\n"/;
hPipe = CreateFile/"\\\\.\\pipe\\testpipe1",
GENERIC_READ,
0, // no sharing
NULL, // default security attributes
OPEN_EXISTING, // opens existing pipe
0, // 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/
{
printf/"Could not open pipe %d\n", GetLastError///;
return -1;
}

// All pipe instances are busy, so wait for sometime.

if / ! WaitNamedPipe/"\\\\.\\pipe\\testpipe1", NMPWAIT_USE_DEFAULT_WAIT//
{
printf/"Could not open pipe: wait timed out.\n"/;
}
}


char *message = "hello";
DWORD cbToWrite = /strlen/message/+1/*sizeof/message[0]/;

DWORD bytes_to_read = 2000;
char * buf = reinterpret_cast<char *="">/malloc/bytes_to_read//;
DWORD bytes_read;

printf/"Waiting for read\n"/;
bytes_read = 0;
ReadFile/hPipe, buf, bytes_to_read, &amp;bytes_read, 0/;

if /bytes_read &lt;= 0/
{
printf/"ReadFile from pipe failed. GLE \n"/;
}
else
printf/"Read %d bytes: %s\n", bytes_read, buf/;

CloseHandle/hPipe/;
return 0;
}


</char></stdio.h></windows.h></stdio.h></windows.h>

卫东

赞同来自:

在服务器端时,您决定打破连接时,您必须使用链:

1/ CloseHandle /喇叭/;

2/ DisconnectNamedPipe /喇叭/;

要回复问题请先登录注册