Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Nazwany klient potoku używa funkcji CreateFile, aby otworzyć dojście do nazwanego potoku. Jeśli potok istnieje, ale wszystkie jego wystąpienia są zajęte, createFile zwraca INVALID_HANDLE_VALUE, a funkcja GetLastError zwraca ERROR_PIPE_BUSY. W takim przypadku klient nazwanego potoku używa WaitNamedPipe funkcji oczekiwania na udostępnienie wystąpienia nazwanego potoku.
Funkcja CreateFile kończy się niepowodzeniem, jeśli określony dostęp jest niezgodny z określonym dostępem (dwukierunkowy, wychodzący lub przychodzący) podczas tworzenia potoku przez serwer. W przypadku potoku dwustronnego klient może określić dostęp do odczytu, zapisu lub odczytu/zapisu; dla potoku wychodzącego (serwer tylko do zapisu) klient musi określić dostęp tylko do odczytu; i dla potoku przychodzącego (serwer tylko do odczytu) klient musi określić dostęp tylko do zapisu.
Dojście zwrócone przez CreateFile domyślne tryb odczytu bajtów, tryb oczekiwania blokowania, tryb nakładania się wyłączone i tryb zapisu wyłączone. Klient potoku może używać CreateFile, aby włączyć nakładający się tryb, określając FILE_FLAG_OVERLAPPED lub aby włączyć tryb zapisu, określając FILE_FLAG_WRITE_THROUGH. Klient może użyć funkcji SetNamedPipeHandleState, aby włączyć tryb bezblokowania, określając PIPE_NOWAIT lub aby włączyć tryb odczytu komunikatów, określając PIPE_READMODE_MESSAGE.
W poniższym przykładzie pokazano klienta potoku, który otwiera nazwany potok, ustawia uchwyt potoku w trybie odczytu komunikatów, używa funkcji WriteFile do wysyłania żądania do serwera i używa funkcji ReadFile do odczytu odpowiedzi serwera. Tego klienta potoku można używać z dowolnymi serwerami typu komunikatów wymienionymi w dolnej części tego tematu. Jednak w przypadku serwera typu bajtowego ten klient potoku kończy się niepowodzeniem, gdy wywołuje SetNamedPipeHandleState, aby zmienić tryb na tryb odczytu komunikatów. Ponieważ klient odczytuje z potoku w trybie odczytu komunikatów, możliwe jest, że operacja ReadFile zwrócić zero po odczytaniu komunikatu częściowego. Dzieje się tak, gdy komunikat jest większy niż bufor odczytu. W takiej sytuacji GetLastError zwraca ERROR_MORE_DATA, a klient może odczytać pozostałą część komunikatu przy użyciu dodatkowych wywołań ReadFile.
Tego klienta potoku można używać z dowolnymi serwerami potoku wymienionymi w sekcji Zobacz również.
#include <windows.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#define BUFSIZE 512
int _tmain(int argc, TCHAR *argv[])
{
HANDLE hPipe;
LPTSTR lpvMessage=TEXT("Default message from client.");
TCHAR chBuf[BUFSIZE];
BOOL fSuccess = FALSE;
DWORD cbRead, cbToWrite, cbWritten, dwMode;
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\mynamedpipe");
if( argc > 1 )
lpvMessage = argv[1];
// Try to open a named pipe; wait for it, if necessary.
while (1)
{
hPipe = CreateFile(
lpszPipename, // pipe name
GENERIC_READ | // read and write access
GENERIC_WRITE,
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)
{
_tprintf( TEXT("Could not open pipe. GLE=%d\n"), GetLastError() );
return -1;
}
// All pipe instances are busy, so wait for 20 seconds.
if ( ! WaitNamedPipe(lpszPipename, 20000))
{
printf("Could not open pipe: 20 second wait timed out.");
return -1;
}
}
// The pipe connected; change to message-read mode.
dwMode = PIPE_READMODE_MESSAGE;
fSuccess = SetNamedPipeHandleState(
hPipe, // pipe handle
&dwMode, // new pipe mode
NULL, // don't set maximum bytes
NULL); // don't set maximum time
if ( ! fSuccess)
{
_tprintf( TEXT("SetNamedPipeHandleState failed. GLE=%d\n"), GetLastError() );
return -1;
}
// Send a message to the pipe server.
cbToWrite = (lstrlen(lpvMessage)+1)*sizeof(TCHAR);
_tprintf( TEXT("Sending %d byte message: \"%s\"\n"), cbToWrite, lpvMessage);
fSuccess = WriteFile(
hPipe, // pipe handle
lpvMessage, // message
cbToWrite, // message length
&cbWritten, // bytes written
NULL); // not overlapped
if ( ! fSuccess)
{
_tprintf( TEXT("WriteFile to pipe failed. GLE=%d\n"), GetLastError() );
return -1;
}
printf("\nMessage sent to server, receiving reply as follows:\n");
do
{
// Read from the pipe.
fSuccess = ReadFile(
hPipe, // pipe handle
chBuf, // buffer to receive reply
BUFSIZE*sizeof(TCHAR), // size of buffer
&cbRead, // number of bytes read
NULL); // not overlapped
if ( ! fSuccess && GetLastError() != ERROR_MORE_DATA )
break;
_tprintf( TEXT("\"%s\"\n"), chBuf );
} while ( ! fSuccess); // repeat loop if ERROR_MORE_DATA
if ( ! fSuccess)
{
_tprintf( TEXT("ReadFile from pipe failed. GLE=%d\n"), GetLastError() );
return -1;
}
printf("\n<End of message, press ENTER to terminate connection and exit>");
_getch();
CloseHandle(hPipe);
return 0;
}
Tematy pokrewne