Тема: IPC між програмами написаними на С++ і C# за допомогою Named Pipe
Має бути так: Програма написана на C# (сервер) запускає програму написану на С++ (клієнт) і ця програма передає повідомлення (у вигляді байтів) у програму сервер
Код клієнта
#include <stdio.h>
#include <windows.h>
int main(int argc, char *argv[])
{
HANDLE hPipe;
//Pipe Init Data
const unsigned short bufSize = 1000;
char buf[bufSize];
LPTSTR lpszPipename = TEXT("\\\\.\\pipe\\myNamedPipe");
DWORD cbWritten;
DWORD dwBytesToWrite = (DWORD)strlen(buf);
hPipe = CreateFile(lpszPipename, GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);
if (hPipe == NULL || hPipe == INVALID_HANDLE_VALUE)
{
printf("Could not open the pipe - (error %d)\n", GetLastError());
}
else
{
do
{
printf("Enter your message: ");
scanf("%s", buf);
WriteFile(hPipe, buf, dwBytesToWrite, &cbWritten, NULL);
memset(buf, 0, bufSize);
} while (TRUE);
CloseHandle(hPipe);
}
printf("App is stopped");
getchar();
}
Код серверу (складається з двох файлів класу NamedPipeServer і функції main)
using System;
using Microsoft.Win32.SafeHandles;
using System.Text;
using System.Runtime.InteropServices;
using System.Threading;
using System.IO;
namespace CSNamedPipe
{
public class NamedPipeServer
{
[DllImport("kernel32.dll", SetLastError = true)]
public static extern SafeFileHandle CreateNamedPipe(
String pipeName,
uint dwOpenMode,
uint dwPipeMode,
uint nMaxInstances,
uint nOutBufferSize,
uint nInBufferSize,
uint nDefaultTimeOut,
IntPtr lpSecurityAttributes);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int ConnectNamedPipe(
SafeFileHandle hNamedPipe,
IntPtr lpOverlapped);
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int DisconnectNamedPipe(
SafeFileHandle hNamedPipe);
public const uint DUPLEX = (0x00000003);
public const uint FILE_FLAG_OVERLAPPED = (0x40000000);
public class Client
{
public SafeFileHandle handle;
public FileStream stream;
}
public const int BUFFER_SIZE = 1000;
public Client clientse = null;
public string pipeName;
Thread listenThread;
SafeFileHandle clientHandle;
public NamedPipeServer(string PName)
{
pipeName = PName;
}
public void Start()
{
listenThread = new Thread(new ThreadStart(ListenForClients));
listenThread.Start();
}
private void ListenForClients()
{
while (true)
{
clientHandle = CreateNamedPipe(
pipeName,
DUPLEX | FILE_FLAG_OVERLAPPED,
0,
255,
BUFFER_SIZE,
BUFFER_SIZE,
0,
IntPtr.Zero
);
//could not create named pipe
if (clientHandle.IsInvalid)
{
return;
}
int success = ConnectNamedPipe(clientHandle, IntPtr.Zero);
//could not connect client
if (success == 0)
{
return;
}
clientse = new Client();
clientse.handle = clientHandle;
clientse.stream = new FileStream(clientse.handle, FileAccess.Read, BUFFER_SIZE);
Thread readThread = new Thread(new ThreadStart(Read));
readThread.Start();
Thread.Sleep(1000);
}
}
private void Read()
{
byte[] buffer = null;
ASCIIEncoding encoder = new ASCIIEncoding();
while (true)
{
int bytesRead = 0;
buffer = new byte[BUFFER_SIZE];
bytesRead = clientse.stream.Read(buffer, 0, BUFFER_SIZE);
//client has disconnected
if (bytesRead == 0)
{
break;
}
Console.WriteLine("read >>> " + Encoding.ASCII.GetString(buffer));
buffer.Initialize();
Thread.Sleep(1000);
}
//clean up resources
clientse.stream.Close();
clientse.handle.Close();
}
public void StopServer()
{
//clean up resources
DisconnectNamedPipe(clientHandle);
listenThread.Abort();
}
}
}
using System;
namespace CSNamedPipe
{
class Program
{
static void Main(string[] args)
{
NamedPipeServer PServer1 = new NamedPipeServer(@"\\.\pipe\myNamedPipe");
PServer1.Start();
Console.ReadKey();
PServer1.StopServer();
}
}
}
Проблема в тому що повідомлення проходять не повні або взагалі не приходять
Приклад вводу - 1234567890qwertyuio
Сервер виводить - 123
Я ще пробував імпортувати функцію CreateFile i ReadFile в сервер але не вийшло підібрати параметри... тому користуюся інструментами C# FileStream
В чому може бути проблема ? Чому повідомлення не передаються повністю ?