Socket: Send vs. BeginSend / EndSend performance problem

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
 
T

tamberg

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

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top