By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
440,854 Members | 833 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 440,854 IT Pros & Developers. It's quick & easy.

IOCP io strategy benchmarking

P: n/a
Hello,

I'm benchmarking .NET IO Completion Ports in C#. For that purpose I've
written two basic ECHO servers that I'm testing under high load (over
2.000 clients).

IOCP in .Net is fantastic, the code is very straightforward and clean,
except that I'm having performance problems. The server is actually
slower than a native basic 1 thread per client implementation. I must
admit however that when I increase the number of clients to 1.000 or
2.000 it continues to work (slowly) when the other one is rendered
unusable (there are too many threads of course). I've written a simple
native IOCP server en C just for fun and I am amazed when I compare them.

I am no C# expert so I'll show you the code, hoping that someone can tell
me if I'm doing anything wrong, and if not, could help me understand what
cripples the program.

BTW if you know of any reasonably good free profiler for .NET that would
be great (and very helpful of course).

Here comes the code :

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

class Echo_client
{
Socket client = null;
int state = 0;

// io operations
AsyncCallback work_callback = null;
byte[] buffer;
int packet_max = 1024;

enum type { recv, send };

public Echo_client( Socket cli )
{
state = 0;
client = cli;
work_callback = new AsyncCallback(work);
}

public void init_work( object o )
{
buffer = new byte[packet_max];

// Asynchronous operation
client.BeginReceive( buffer, 0, packet_max, SocketFlags.None,
work_callback, type.recv );
state = 0;
}

public void work( IAsyncResult ar )
{
// state 0 is pending recv or send
if( state==0 )
{
if( !client.Connected )
{
// one end has disconected
state = 1;
}
if( (type)ar.AsyncState == type.recv )
{
// the client sent data
int read = client.EndReceive( ar );
if( read==0 ) {
state=1;
}
// send it back
client.BeginSend( buffer, 0, read, SocketFlags.None,
work_callback, type.send );
}
else if( (type)ar.AsyncState == type.send )
{
// finished sendind data to the server
int sent = client.EndSend( ar );
if( sent==0 ) {
state=1;
}
// get new bytes from the client
client.BeginReceive( buffer, 0, packet_max,
SocketFlags.None, work_callback, type.recv );
}
}
// state 1 is one end has closed connection
else if( state==1 )
{
client.Close();
}
}
}

class Echo
{
Thread main_thread = null;
ThreadStart main_threadstart = null;

public void run()
{
// loop on accept connexions
TcpListener listener = new TcpListener( IPAddress.Any, 1234 );

listener.Start();
while( true )
{
Socket client_socket = listener.AcceptSocket();

Echo_client client = new Echo_client( client_socket );

client.init_work( 0 );
}
}

////
// loads the module
public bool load( )
{
// launch the module in a separate thread
main_threadstart = new ThreadStart( run );
main_thread = new Thread( main_threadstart );
main_thread.Start();

// give the thread a chance to start
Thread.Sleep( 0 );

return true;
}

////
// cleanly unloads the module
public void unload()
{
main_thread.Abort();
}

}

--
_|_|_| CnS
_|_| for(n=0;b;n++)
_| b&=b-1; /*pp.47 K&R*/
Nov 15 '05 #1
Share this question for a faster answer!
Share on Google+

This discussion thread is closed

Replies have been disabled for this discussion.