Original Post
Hey, I'm using datagrams on a small test program in order to maximize performance. I'm creating 2500 datagram sockets, each socket sending a packet of 50 bytes, in localhost, on a powerful machine (WinXP SP2, Athlon 64 3500+). Well, believe it or not, it takes 810 milliseconds to send 2500 packets (or 125 KB). The CPU usage rockets to 100%, from which 75% are used by the "SYSTEM" process, and 25% by the test.exe process. It doesn't matter if a server is listening to the destination address or not, or if the server is on the same machine or on a different one. I've made a dirty app demonstrating the "problem" (it's 100 lines, please have a look if you got 5 minutes):
#include <winsock2.h>
#include <windows.h>
#include <stdio.h>
#include "CTime.h"
class CClient
{
protected:
SOCKET m_socket; // socket connection
struct sockaddr_in m_myAdr; // client address
struct sockaddr_in m_adr; // destination address
public:
CClient(const char *hostName, const unsigned int port)
{
m_socket = INVALID_SOCKET;
m_socket = socket(AF_INET, SOCK_DGRAM, 0);
if (m_socket == INVALID_SOCKET)
{
throw "Can't create client socket";
}
m_myAdr.sin_family = AF_INET;
m_myAdr.sin_port = 0;
m_myAdr.sin_addr.s_addr = INADDR_ANY;
if (bind(m_socket, (struct sockaddr *)&m_myAdr, sizeof(m_myAdr)) != 0)
{
throw "Can't bind client socket";
}
struct sockaddr_in destAdr;
destAdr.sin_family = AF_INET;
destAdr.sin_port = htons(port);
destAdr.sin_addr.s_addr = inet_addr(hostName);
if (destAdr.sin_addr.s_addr == INADDR_NONE)
{
throw "Can't find destination address";
}
m_adr = destAdr;
/// flags the sockets as non-blocking
u_long flag = 1;
if (ioctlsocket(m_socket, FIONBIO, &flag) != 0)
{
throw "Can't ioctl socket";
}
}
void process()
{
char buf[256];
int bytes = sendto(m_socket, buf, 50, 0,
(struct sockaddr *)&m_adr, sizeof(struct sockaddr_in));
}
};
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpCmdLine, int nCmdShow)
{
/// init WSA
WORD wVersionRequested;
WSADATA wsaData;
int err;
wVersionRequested = MAKEWORD( 2, 2 );
err = WSAStartup( wVersionRequested, &wsaData );
#define NBSOCKETS 2500
CClient *clients[NBSOCKETS];
for (unsigned int i = 0; i < NBSOCKETS; i++)
clients = new CClient("127.0.0.1", 7000);
while (1)
{
CTime ct;
/// sending one packet per client:
for (i = 0; i < NBSOCKETS; i++)
clients->process();
float e = ct.getElapsed();
/// sleep a little (100 ms at worse)
int sleep = 100 - (int)(e * 1000.0f);
if (sleep < 10)
sleep = 10;
Sleep(sleep);
char str[256];
sprintf(str, "Elapsed: %.1f ms\n", e * 1000.0f);
OutputDebugString(str);
}
return 0;
}
Why is it so slow ? I am quite amazed at these results. Y.