CreateNamedPipe : این تابع پس از ساخته شدن یک هندل برای کنترل برمیگرداند و سپس شروع به کار میکند.

سینتکس این تابع به صورت زیر میباشد .

HANDLE WINAPI CreateNamedPipe(
  LPCTSTR               lpName,
  DWORD                 dwOpenMode,
  DWORD                 dwPipeMode,
  DWORD                 nMaxInstances,
  DWORD                 nOutBufferSize,
  DWORD                 nInBufferSize,
  DWORD                 nDefaultTimeOut,
  LPSECURITY_ATTRIBUTES lpSecurityAttributes
);

معرفی آرگمان ها :
lpName : این آرگمان از نوع یونیکد است و حاوی نام pipe میباشد و حتما باید به صورت زیر باشد:
\\.\pipe\pipename
dwOpenMode : این آرگمان شامل فلگ هایی برای تعیین وضعیت ورودی خروجی ، ورودی ، .... pipe میباشد .
dwPipeMode : این آرگمان فلگ هایی رو رو از برنامه نویس به عنوان یک استاندارد برای تبادل اطلاعات بین دو پراسس میگیرد هر دو پراسس با یک استاندارد دیتا ها را بین همدیگر مبادله کنند . پرچم های آن به شرح زیر میباشد :
PIPE_TYPE_BYTE : این فلگ تعیین میکند که دیتا ها باید بصورت جریان بایتی فرستاده شود.(0x00000000)
PIPE_TYPE_MESSAGE : این فلگ تعیین میکند که جریاین بصورت یه پیغام میباشد . در این حالت تابع  GetLastError مقدار ERROR_MORE_DATA را زمانی برمیگرداند که پیغام به صورت کامل دریافت نشده باشد .(0x00000004)
nMaxInstances : این آرگمان حداکثر مقداری است که میتواند پیپ ما مورد استفاده قرار گیرد . این مقدار میتواند از 1 تا 255 متغییر باشد . اگر مقدار داده شده از مقدار حداکثر (PIPE_UNLIMITED_INSTANCES) بیشتر باشد تابع GetLastError مقدار (ERROR_INVALID_PARAMETER) را برمیگرداند .

nInBufferSize : این آرگومان تعداد بایت های رزرو برای بایت های ورودی را مشخص میسازد .

در پایان مثال جامعی ارائه گردیده .

________________________________________

ConnectNamedPipe : این تابع برای فعال سازی پیپ سرور و همچنین باعث میشود سرور تا زمانی که کلاینت به آن پیپ متصل نگردیده منتظر بماند .

BOOL WINAPI ConnectNamedPipe(
  HANDLE       hNamedPipe,
  LPOVERLAPPED lpOverlapped
);

معرفی آرگمان ها :

hNamedPipe : هندلی که با استفاده از تابع CreateNamedPipe برگردانده میشود در این آرگمان قرار میگیرد .

در پایان مثال جامعی ارائه گردیده .


برنامه نمونه : در این برنامه ابتدا برنامه سرور ساخته و اجرا میگردد و سپس برنامه کلاینت اجرا میشود ، در ابتدا برنامه سرور یک pipe را سخته و منتظر میشود تا برنامه کلاینت به آن pipe متصل گردد ، سپس برنامه سرور ساختمان sendData را به داخل پیپ میفرستد و برنامه کلاینت آن را دریافت و در getData قرار میدهد و مقادیر آن را نمایش میدهد .

سپس برنامه کلاینت مقدار عددی 100 را درون pipe میفرستد و برنامه سرور آن را دریافت و در متغیری ریخته و سپس آن را نمایش میدهد .

این pipe به صورت دو طرفه ساحخته شده بر حسب نیاز میتوانید آن را یک طرفه نیز بسازید . برای تغییر وضعیت در آن میتوان آرگمان دوم تابع CreateNamedPipe را تغییر دهید .


برنامه اول (برنامه سرور) :


//// SERVER PROGRAM ////

#include <iostream>
#include <windows.h>
#include <string>
using namespace std;

struct sendData
{
int num01;
string str;
sendData()
{
num01 = 20;
str = "amid";
}
};

int main(int argc, const char **argv)
{
cout << "Creating an instance of a named pipe..." << endl;

// Create a pipe to send data
HANDLE pipe = CreateNamedPipe(
TEXT("\\\\.\\pipe\\my_pipe"), // name of the pipe
PIPE_ACCESS_OUTBOUND | PIPE_ACCESS_INBOUND, // 2-way pipe -- send and receive
PIPE_TYPE_BYTE, // send data as a byte stream
1, // only allow 1 instance of this pipe
0, // no outbound buffer
0, // no inbound buffer
0, // use default wait time
NULL // use default security attributes
);

if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
cout << "Failed to create outbound pipe instance.";
// look up error code here using GetLastError()
system("pause");
return 1;
}

cout << "Waiting for a client to connect to the pipe..." << endl;

// This call blocks until a client process connects to the pipe
BOOL result = ConnectNamedPipe(pipe, NULL);
if (!result)
{
cout << "Failed to make connection on named pipe." << endl;
// look up error code here using GetLastError()
CloseHandle(pipe); // close the pipe
system("pause");
return 1;
}

cout << "Sending data to pipe..." << endl;

// This call blocks until a client process reads all the data
sendData *data = new sendData();

DWORD numBytesWritten = 0;
result = WriteFile(
pipe, // handle to our outbound pipe
data, // data to send
1 * sizeof(sendData), // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);

if (result)
{
cout << "Number of bytes sent: " << numBytesWritten << endl;
}
else
{
cout << "Failed to send data." << endl;
// look up error code here using GetLastError()
}

//get data from client

cout << "Reading data from pipe..." << endl;

// The read operation will block until there is data to read

int *buffer = new int();
DWORD numBytesRead = 0;
BOOL result2 = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
/*127*/1 * sizeof(int), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);

if (result2)
{
cout << "Number of bytes read : " << numBytesRead << endl;
cout << "Message : " << *buffer << endl;
}
else
{
cout << "Failed to read data from the pipe." << endl;
}

// Close the pipe (automatically disconnects client too)
CloseHandle(pipe);

cout << "Done." << endl;

system("pause");
return 0;
}


برنامه دوم (برنامه کلاینت) :


///// CLIENT PROGRAM /////

#include <iostream>
#include <windows.h>
#include <string>
using namespace std;

struct getData
{
int num;
string str;
getData()
{
num = 1;
str = "null";
}
};

int main(int argc, const char **argv)
{
cout << "Connecting to pipe..." << endl;

// Open the named pipe
// Most of these parameters aren't very relevant for pipes.
HANDLE pipe = CreateFile(
TEXT("\\\\.\\pipe\\my_pipe"),
GENERIC_READ | GENERIC_WRITE, // need read and write access
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);

if (pipe == INVALID_HANDLE_VALUE)
{
cout << "Failed to connect to pipe." << endl;
// look up error code here using GetLastError()
system("pause");
return 1;
}

cout << "Reading data from pipe..." << endl;

// The read operation will block until there is data to read

getData *buffer = new getData();

DWORD numBytesRead = 0;
BOOL result = ReadFile(
pipe,
buffer, // the data from the pipe will be put here
1 * sizeof(getData), // number of bytes allocated
&numBytesRead, // this will store number of bytes actually read
NULL // not using overlapped IO
);

if (result)
{
cout << "Number of bytes read: " << numBytesRead << endl;
cout << "Message num: " << buffer->num << endl;
cout << "Message str: " << buffer->str << endl;
}
else
{
cout << "Failed to read data from the pipe." << endl;
}

//send data to server

cout << "sending data to pipe ..." << endl;

int *data = new int();
*data = 100;
DWORD numBytesWritten = 0;
result = WriteFile(
pipe, // handle to our pipe
data, // data to send to server
1 * sizeof(int), // length of data to send (bytes)
&numBytesWritten, // will store actual amount of data sent
NULL // not using overlapped IO
);

if (result)
{
cout << "Number of bytes sent : " << numBytesWritten << endl;
}
else
{
cout << "Failed to send data." << endl;
// look up error code here using GetLastError()
}

// Close our pipe handle
CloseHandle(pipe);

cout << "Done." << endl;

system("pause");
return 0;
}


pipe