📜 ⬆️ ⬇️

IPC: Sockets vs. Named Pipes

Absolute numbers don't make much sense, but as a comparison, information is of some value.

Conditions


Windows 7 x64 with updates
AMD Athlon X2 4600+ (2.41GHz)
DDR2 2GB
.Net Framework 3.5, classes from FCL.
Two 64-bit processes with no additional privileges.
Kaspersky Anti-Virus is turned off. With it, socket results are significantly worse.
Sockets and named pipes in asynchronous mode.
Buffer sizes were selected optimal, experimentally for each type of IPC.

results


Sockets
One-way transfer speed - 160 megabytes per second (105 with antivirus)
CPU usage - 90%, of which about 2/3 in the core
RAM - 4-5 megabytes per process, did not grow with time

Named Pipes
One-way transfer speed - 755 megabytes per second (the antivirus does not affect)
CPU usage - 80%, of which about 2/3 in the core
RAM - 4-5 megabytes per process, did not grow with time
')

Source


Sockets
using System;
using System.IO.Pipes;
using System.Net;
using System.Net.Sockets;

namespace Server
{
public static class Program
{
private static byte [] buffer = new byte [512 * 1024];

private static void OnSocketSend(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;

client.EndSend(ar);
client.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, OnSocketSend, client);
}

public static void Main( string [] args)
{
Socket server = new Socket(AddressFamily.InterNetwork, SocketType. Stream , ProtocolType.Tcp);

server.Bind( new IPEndPoint(IPAddress.Loopback, 5000));
server.Listen(10);

while ( true )
{
Socket client = server.Accept();

client.SendBufferSize = 2 * buffer.Length;
client.BeginSend(buffer, 0, buffer.Length, SocketFlags.None, OnSocketSend, client);

Console .WriteLine( "CONNECTED" );
}
}
}
}


* This source code was highlighted with Source Code Highlighter .


using System;
using System.Diagnostics;
using System.IO.Pipes;
using System.Net;
using System.Net.Sockets;

namespace Client
{
public static class Program
{
private static byte [] buffer = new byte [512 * 1024];
private static Stopwatch watch = new Stopwatch();
private static long traffic = 0;
private static int step = 0;

private static void OnSocketReceive(IAsyncResult ar)
{
Socket client = (Socket)ar.AsyncState;

traffic += client.EndReceive(ar);
step++;

if ((step % 1000) == 0)
{
watch.Stop();

Console .WriteLine(
"{0} MB/s" ,
(1000 * (traffic >> 20)) / watch.ElapsedMilliseconds);

watch.Start();
}

client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, OnSocketReceive, client);
}

public static void Main( string [] args)
{
Socket client = new Socket(AddressFamily.InterNetwork, SocketType. Stream , ProtocolType.Tcp);

client.ReceiveBufferSize = 2 * buffer.Length;
client.Connect( new IPEndPoint(IPAddress.Loopback, 5000));

watch.Start();

client.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, OnSocketReceive, client);

Console .WriteLine( "CONNECTED" );
Console .ReadLine();
}
}
}


* This source code was highlighted with Source Code Highlighter .

Named Pipes

using System;
using System.IO.Pipes;
using System.Net;
using System.Net.Sockets;

namespace Server
{
public static class Program
{
private static byte [] buffer = new byte [256 * 1024];

private static void OnPipeSend(IAsyncResult ar)
{
NamedPipeServerStream server = (NamedPipeServerStream)ar.AsyncState;

server.EndWrite(ar);
server.BeginWrite(buffer, 0, buffer.Length, OnPipeSend, server);
}

public static void Main( string [] args)
{
NamedPipeServerStream server = new NamedPipeServerStream( "TestPipe" , PipeDirection.InOut, 1, PipeTransmissionMode. Byte , PipeOptions.Asynchronous, 1024 * 1024, 1024 * 1024);

server.WaitForConnection();
server.BeginWrite(buffer, 0, buffer.Length, OnPipeSend, server);

Console .WriteLine( "CONNECTED" );
Console .ReadLine();
}
}
}


* This source code was highlighted with Source Code Highlighter .


using System;
using System.Diagnostics;
using System.IO.Pipes;
using System.Net;
using System.Net.Sockets;

namespace Client
{
public static class Program
{
private static byte [] buffer = new byte [256 * 1024];
private static Stopwatch watch = new Stopwatch();
private static long traffic = 0;
private static int step = 0;

private static void OnPipeReceive(IAsyncResult ar)
{
NamedPipeClientStream client = (NamedPipeClientStream)ar.AsyncState;

traffic += client.EndRead(ar);
step++;

if ((step % 1000) == 0)
{
watch.Stop();

Console .WriteLine(
"{0} MB/s" ,
(1000 * (traffic >> 20)) / watch.ElapsedMilliseconds);

watch.Start();
}

client.BeginRead(buffer, 0, buffer.Length, OnPipeReceive, client);
}

public static void Main( string [] args)
{
NamedPipeClientStream client = new NamedPipeClientStream( "." , "TestPipe" , PipeDirection.InOut, PipeOptions.Asynchronous);

client.Connect();

watch.Start();

client.BeginRead(buffer, 0, buffer.Length, OnPipeReceive, client);

Console .WriteLine( "CONNECTED" );
Console .ReadLine();
}
}
}


* This source code was highlighted with Source Code Highlighter .

Source: https://habr.com/ru/post/81067/


All Articles