Easy networking trouble in Win XP

Hi!
I am trying to send tiny pieces of data over a TCP socket several times per second, while having the Nagle algorithm disabled (it is a time critical application). After setting SO_SNDBUF to 1 for instantly sending data upon calling send(), this function freezes about 200 or 300 milliseconds. I also tried setting TCP_NODELAY to true and false, but it doesn't really do anything (using it without SO_SNDBUF=1 simply leaves Nagle on).
Note that the amount of data that is being transferred at once is only a few bytes.
This behavior is not met on a Windows 7 machine, and it only occurs on the server side (while sending the data to an accept()ed socket).
I'm compiling the code with GCC.

Sorry about asking this rather silly question, but I just can't seem to find a solution...

Many thanks!
Here's a (not) working example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#define _WIN32_WINNT 0x501
#include <windows.h>
#include <ws2tcpip.h>
#include <fcntl.h>
#include <fstream>
#include <string>
#include <boost/date_time/posix_time/posix_time.hpp>
using namespace std;

#define LISTENPORT "5284"
#define SOCKETBACKLOG 6
#define MAXMSGSIZE 1024

std::string now_str(){
    const boost::posix_time::ptime now=boost::posix_time::microsec_clock::local_time();
    const boost::posix_time::time_duration td = now.time_of_day();
    const long hours=td.hours();
    const long minutes=td.minutes();
    const long seconds=td.seconds();
    const long milliseconds=td.total_milliseconds()-((hours*3600+minutes*60+seconds)*1000);
    char buf[40];
    sprintf(buf,"%02ld:%02ld:%02ld.%03ld",hours,minutes,seconds,milliseconds);
    return buf;
};
ofstream Log;

class Server{
    public:
    Server();
    int InitServer();
    int ProcessServer();
    int CleanServer();
    protected:
    int ListenSocket,AcceptSocket;
    addrinfo *ListenSocketData;
    sockaddr *AcceptSocketData;
    fd_set SocketList,SocketListTemp;
    bool Dc;
    int InitWsa();
    int CleanWsa();
    int Listen();
};
int Server::InitWsa(){
    WSADATA WsaData;
	if(WSAStartup(MAKEWORD(1,1),&WsaData)!=0){
	    MessageBox(NULL,"Failed initializing WSA.","Server",MB_ICONERROR);
	    return -1;
	};
	return 0;
};
int Server::CleanWsa(){
    if(WSACleanup()!=0){
        MessageBox(NULL,"Failed cleaning WSA.","Server",MB_ICONERROR);
        return -1;
    };
    return 0;
};
int Server::Listen(){
    addrinfo ListenSocketHints;
    ZeroMemory(&ListenSocketHints,sizeof(ListenSocketHints));
    ListenSocketHints.ai_family=AF_INET;
    ListenSocketHints.ai_socktype=SOCK_STREAM;
    ListenSocketHints.ai_flags=AI_PASSIVE;
    getaddrinfo(NULL,LISTENPORT,&ListenSocketHints,&ListenSocketData);
    ListenSocket=socket(ListenSocketData->ai_family,ListenSocketData->ai_socktype,ListenSocketData->ai_protocol);
    bind(ListenSocket,ListenSocketData->ai_addr,ListenSocketData->ai_addrlen);
    listen(ListenSocket,SOCKETBACKLOG);
    FD_SET((unsigned)ListenSocket,&SocketList);
    return 0;
};
Server::Server(){
    ListenSocket=-1;
    ListenSocketData=NULL;
    AcceptSocket=-1;
    AcceptSocketData=NULL;
    Dc=false;
    FD_ZERO(&SocketList);
    FD_ZERO(&SocketListTemp);
    Log.open("Log.log");
};
int Server::InitServer(){
    InitWsa();
    Listen();
    return 0;
};

int Server::ProcessServer(){
    int ClientSocketDataSize=sizeof(addrinfo),MessageSize;
    char Message[MAXMSGSIZE];
    timeval NoBlock;
    ZeroMemory(&NoBlock,sizeof(NoBlock));
    while(1){
        if(Dc)return 0;
        SocketListTemp=SocketList;
        select(0,&SocketListTemp,NULL,NULL,&NoBlock);
        if(FD_ISSET(ListenSocket,&SocketListTemp)){
            AcceptSocket=accept(ListenSocket,AcceptSocketData,&ClientSocketDataSize);
            int Parameter(1);
            setsockopt(AcceptSocket,IPPROTO_TCP,TCP_NODELAY,(char*)&Parameter,sizeof(int));
            //setsockopt(AcceptSocket,SOL_SOCKET,SO_SNDBUF,(char*)&Parameter,sizeof(int));
            FD_SET((unsigned)AcceptSocket,&SocketList);
        };
        if(AcceptSocket==-1)continue; //no connection yet
        Log.write("Pre-send check at ",strlen("Pre-send check at "));
        Log.write(now_str().c_str(),strlen(now_str().c_str()));
        Log.write("\n",1);
        const char Buffer[strlen("Choo choo")+1]="Choo choo";
        send(AcceptSocket,Buffer,strlen("Choo choo")+1,0);
        Log.write("Post-send check at ",strlen("Post-send check at "));
        Log.write(now_str().c_str(),strlen(now_str().c_str()));
        Log.write("\n",1);
        if(!FD_ISSET(AcceptSocket,&SocketListTemp))continue;
        MessageSize=recv(AcceptSocket,Message,MAXMSGSIZE,0);
        if(MessageSize<=0){
            Dc=true;
            continue;
        };
    };
};

int Server::CleanServer(){
    closesocket(ListenSocket);
    freeaddrinfo(ListenSocketData);
    FD_ZERO(&SocketList);
    return CleanWsa();
};

int main(int argc,char* argv[]){
    Server MainServer;
    MainServer.InitServer();
    MainServer.ProcessServer();
    MainServer.CleanServer();
    return 0;
};
(sorry for messy code)

Suppose a client simply connects to this running application, it will start spinning and sending messages to that client. Unfortunately, the messages will not be individual, but grouped in larger packets - about 1000 bytes each (which makes me believe that Nagle is up and running). If I uncomment the SNDBUF line, messages will be individually sent, but the program will freeze for a large amount of time for each send (based on my log file). Any idea what's going on here?
Note: I am obviously not trying to send so many messages per second; this is just an example file.

Credits for the now_str() function go to some guy at StackOverflow (found it on the web a while ago and I keep using it for debugging).

Thanks :D
Ideas?...
Topic archived. No new replies allowed.