Click here to Skip to main content
15,892,298 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
i have this code PIPE Server C++
C++
<pre>#include <stdio.h>
#include <stdint.h>
#include <winsock.h>
#include <string>

// see https://msdn.microsoft.com/en-us/library/bb546085(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
// for information on creating pipe clients and servers in c++

using namespace std;

#pragma pack(1)
typedef struct {
	int8_t command;
	int32_t sockid;
	int32_t datasize;
} PipeHeader;
#pragma pack()

int wmain(int argc, wchar_t* argv[]) {

	int arrayNumber[70];
	auto pipename = "\\\\.\\pipe\\pipey"; // can be any name, but must start '\\.\pipe\'
	printf("Create pipe '%s'\r\n", pipename);
	auto pipeHandle = CreateNamedPipe(pipename,
		PIPE_ACCESS_DUPLEX,
		PIPE_TYPE_MESSAGE | PIPE_WAIT,
		1,  // # instances
		64, // out buff
		64, // in buff
		0,  // timeout, 0 = default of 50ms
		NULL); // security attrs
	printf("Waiting for pipe connect\r\n");
	if (ConnectNamedPipe(pipeHandle, NULL)) {
		printf("Pipe connected\r\n");
		PipeHeader hdr;
		DWORD bytesRead;
		int8_t cmd = -1;
		while (cmd != 0) {
			if (ReadFile(pipeHandle, &hdr, sizeof(PipeHeader), &bytesRead, NULL)) {
				// you can check or assert here that bytesRead == sizeof(PipeHeader)
				printf("Read %d bytes from pipe, {command: %d, sockid: %d, datasize: %d}\r\n",
					bytesRead, hdr.command, hdr.sockid, hdr.datasize);
				if (hdr.command == 0) { // assume 0 is the exit cmd
					break;
				}
				else if (hdr.command == 1) {
					
					while (true)
					{
						for (size_t i = 0; i < 70; i++)
						{
							 return arrayNumber[i] = i;
							 Sleep(100);
						}
						Sleep(100);
					}
				}
				hdr.command = 4;
				hdr.sockid = 101;
				hdr.datasize *= 2;
				if (WriteFile(pipeHandle, &hdr, sizeof(PipeHeader), &bytesRead, NULL)) {
					printf("Data written to pipe\r\n");
				}
				else {
					printf("Pipe write failed\r\n");
					break;
				}
			}
			else {
				printf("Read error: %d\r\n", GetLastError());
				break; // exit
			}
		}
		if (DisconnectNamedPipe(pipeHandle) == FALSE) {
			printf("Disconnect error: %d\r\n", GetLastError());
		}
	}
	else {
		printf("Pipe connect failed\r\n");
	}
	CloseHandle(pipeHandle);
	printf("Exiting program\r\n");
	return 0;
}


and my client C#, that i want to receive array




C#
<pre>using System;
using System.Runtime.InteropServices;
using System.IO.Pipes;

namespace PIPI_Client
{
    // see https://msdn.microsoft.com/en-us/library/bb546085(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
    // for information on creating pipe clients and servers in c#
    class Program
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
        public struct PipeHeader
        {
            [MarshalAs(UnmanagedType.I1)]
            public byte command;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 sockid;
            public Int32 datasize;
        }

        static void Main(string[] args)
        {
            var pipename = "pipey";
            var pipeClient = new NamedPipeClientStream(pipename);
            Console.WriteLine("Connecting to server pipe '{0}'", pipename);
            pipeClient.Connect();
            var hdr = new PipeHeader();
            var hdrSize = Marshal.SizeOf(hdr);
            hdr.command = 1;
            hdr.sockid = 1912;
            hdr.datasize = 32;
            var buf = Serialize(hdr);
            Console.WriteLine("Writing to server pipe");
            pipeClient.Write(buf, 0, hdrSize);
            pipeClient.Read(buf, 0, hdrSize);
            hdr = (PipeHeader)Deserialize(buf, hdr.GetType());
            Console.WriteLine("Pipe read {{ command: {0}, sockid: {1}, datasize: {2} }}",
                               hdr.command, hdr.sockid, hdr.datasize);

            //receive array from client some where?

            hdr.command = 1; // tell server to disconnect
            buf = Serialize(hdr);
            Console.WriteLine("Sending disconnect");
            pipeClient.Write(buf, 0, hdrSize);
            pipeClient.Close();
            Console.WriteLine("Pipe closed");

            Console.ReadKey();
        }

        public static object Deserialize(byte[] rawdatas, Type anytype)
        {
            int rawsize = Marshal.SizeOf(anytype);
            if (rawsize > rawdatas.Length)
                return null;
            GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
            IntPtr buffer = handle.AddrOfPinnedObject();
            object retobj = Marshal.PtrToStructure(buffer, anytype);
            handle.Free();
            return retobj;
        }

        public static byte[] Serialize(object obj)
        {
            int rawsize = Marshal.SizeOf(obj);
            var rv = new byte[rawsize];
            IntPtr ptr = Marshal.AllocHGlobal(rawsize);
            Marshal.StructureToPtr(obj, ptr, true);
            Marshal.Copy(ptr, rv, 0, rawsize);
            Marshal.FreeHGlobal(ptr);
            return rv;
        }
    }
}


the connection betwen server and client work fine, but i dont know how to pass array to client
=/

What I have tried:

<pre lang="c#"><pre>using System;
using System.Runtime.InteropServices;
using System.IO.Pipes;

namespace PIPI_Client
{
    // see https://msdn.microsoft.com/en-us/library/bb546085(v=vs.110).aspx?cs-save-lang=1&cs-lang=csharp#code-snippet-1
    // for information on creating pipe clients and servers in c#
    class Program
    {
        [StructLayout(LayoutKind.Sequential, Pack = 1, CharSet = CharSet.Ansi)]
        public struct PipeHeader
        {
            [MarshalAs(UnmanagedType.I1)]
            public byte command;
            [MarshalAs(UnmanagedType.I4)]
            public Int32 sockid;
            public Int32 datasize;
        }

        static void Main(string[] args)
        {
            var pipename = "pipey";
            var pipeClient = new NamedPipeClientStream(pipename);
            Console.WriteLine("Connecting to server pipe '{0}'", pipename);
            pipeClient.Connect();
            var hdr = new PipeHeader();
            var hdrSize = Marshal.SizeOf(hdr);
            hdr.command = 1;
            hdr.sockid = 1912;
            hdr.datasize = 32;
            var buf = Serialize(hdr);
            Console.WriteLine("Writing to server pipe");
            pipeClient.Write(buf, 0, hdrSize);
            pipeClient.Read(buf, 0, hdrSize);
            hdr = (PipeHeader)Deserialize(buf, hdr.GetType());
            Console.WriteLine("Pipe read {{ command: {0}, sockid: {1}, datasize: {2} }}",
                               hdr.command, hdr.sockid, hdr.datasize);

            //receive array from client some where?

            hdr.command = 1; // tell server to disconnect
            buf = Serialize(hdr);
            Console.WriteLine("Sending disconnect");
            pipeClient.Write(buf, 0, hdrSize);
            pipeClient.Close();
            Console.WriteLine("Pipe closed");

            Console.ReadKey();
        }

        public static object Deserialize(byte[] rawdatas, Type anytype)
        {
            int rawsize = Marshal.SizeOf(anytype);
            if (rawsize > rawdatas.Length)
                return null;
            GCHandle handle = GCHandle.Alloc(rawdatas, GCHandleType.Pinned);
            IntPtr buffer = handle.AddrOfPinnedObject();
            object retobj = Marshal.PtrToStructure(buffer, anytype);
            handle.Free();
            return retobj;
        }

        public static byte[] Serialize(object obj)
        {
            int rawsize = Marshal.SizeOf(obj);
            var rv = new byte[rawsize];
            IntPtr ptr = Marshal.AllocHGlobal(rawsize);
            Marshal.StructureToPtr(obj, ptr, true);
            Marshal.Copy(ptr, rv, 0, rawsize);
            Marshal.FreeHGlobal(ptr);
            return rv;
        }
    }
}
Posted
Updated 13-Nov-18 8:19am
Comments
tanchusegialai 8-Jul-19 4:27am    
do you have solution for your problem. Would you please post it? I want the same solution.

1 solution

My usual tactic in this kind of situation is to have the client ask the server and have the server reply with what it is asked for. If you can't explicitly have the client to do that then you can revise the programs so the client asks the server, "do you have anything for me?" and the server replies with whatever you have told it to send to the client. I have done this kind of thing several times in the past over raw socket and pipe connections and it works quite well.
 
Share this answer
 
Comments
CesatAGS 16-Nov-18 17:34pm    
you have a demo?

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900