Socket: Send vs. BeginSend / EndSend performance problem

  • Thread starter Thread starter tamberg
  • Start date Start date
T

tamberg

We experience a major performance difference between sync and async
usage of the Socket class. Is there an explanation why the following
program runs about 250 times slower when async is set to true? (scroll
to end of post for usage hint)

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

sealed class EchoS4 {
EchoS4 () {}

static bool async = false;

const int N = 500;

static void Poll (IAsyncResult ar) {
while (!ar.IsCompleted) {
Thread.Sleep(1);
}
}

static void Send (Socket s, byte[] msg) {
if (async) {
IAsyncResult ar = s.BeginSend(msg, 0, msg.Length,
SocketFlags.None, null, null);
Poll(ar);
s.EndSend(ar);
} else {
int n = 0;
do {
n += s.Send(msg, n, msg.Length - n, SocketFlags.None);
} while (n != msg.Length);
}
}

static void Receive (Socket s, byte[] msg) {
if (async) {
int n = 0;
do {
IAsyncResult ar = s.BeginReceive(msg, n, msg.Length - n,
SocketFlags.None, null, null);
Poll(ar);
n += s.EndReceive(ar);
} while (n != msg.Length);
} else {
int n = 0;
do {
n += s.Receive(msg, n, msg.Length - n, SocketFlags.None);
} while (n != msg.Length);
}
}

static void Client (string adr) {
Socket s = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
using (s) {
s.Connect(new IPEndPoint(IPAddress.Parse(adr), 7777));
byte[] msg = new byte[4];
DateTime t0 = DateTime.Now;
int n = N;
while (n != 0) {
Send(s, msg);
Receive(s, msg);
n--;
}
Console.WriteLine((DateTime.Now - t0).TotalMilliseconds);
}
}

static void Server (string adr) {
Socket s0 = new Socket(AddressFamily.InterNetwork,
SocketType.Stream, ProtocolType.Tcp);
s0.Bind(new IPEndPoint(IPAddress.Parse(adr), 7777));
s0.Listen(10);
while (true) {
Socket s1 = s0.Accept();
int n = N;
while (n != 0) {
byte[] msg = new byte[4];
Receive(s1, msg);
Send(s1, msg);
n--;
}
}
}

static void Main (string[] args) {
if (args.Length > 1) {
if (args[0] == "s") {
Server(args[1]);
} else if (args[0] == "c") {
Client(args[1]);
}
}
}
}

// Server usage:

echos4 s 127.0.0.1

// Client usage:

echos4 c 127.0.0.1
 
Thanks. Now it's a lot faster (sync: 20ms / async: 80ms) than before
(sync: 20ms / async 1200ms).
 
Back
Top