Reputation: 307
(Original issue listed below)
It turned out I had a "slow consumer" issue. Since I don't have control over the server program, I tried setting
setsockopt(m_sock,
IPPROTO_TCP,
TCP_NODELAY,
(char *) &flag,
sizeof(int));
but I still get to the point where write to the socket takes a few seconds. Am I missing something? Original Issue: I've created a socket using
m_sock = socket(AF_INET, SOCK_STREAM, 0);
Set it to non blocking:
int opts = fcntl ( m_sock, F_GETFL );
opts = ( opts | O_NONBLOCK );
fcntl ( m_sock, F_SETFL,opts );
and then send
send(m_sock, v_pData, v_iDataSize, MSG_NOSIGNAL);
I'm sending about 200bytes , 5 times a second after about 2 minutes it creates a big buffer and a big delay in sending the data. Is there a way to improve the send perofrmance?
First Edit: I'm adding more code as for how I create and use the socket:
m_sock = socket ( AF_INET,
SOCK_STREAM,
0 );
if ( ! is_valid() )
return false;
int on = 1;
if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* ) &on, sizeof ( on ) ) == -1 )
return false;
server = gethostbyname(host.c_str());
if (server == NULL) {
return false;
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
bcopy((char *)server->h_addr,
(char *)&serv_addr.sin_addr.s_addr,
server->h_length);
serv_addr.sin_port = htons(portno);
set_non_blocking(true);// Code for set_non_blocking mentioned above
connect(m_sock,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) ;
I write to the socket using:
iOut = send(m_sock, v_pData, v_iDataSize, MSG_NOSIGNAL);
Upvotes: 0
Views: 3750
Reputation: 1085
You see the Nagle's algorithm in action.
Just set the TCP_NODELAY socket option:
int value = 1;
setsockopt(m_sock, IPPROTO_TCP, TCP_NODELAY, (void*)&value, sizeof(value));
I don't think you need O_NONBLOCK, but that highly depends on your use case.
Upvotes: 1
Reputation: 1
Particularily if you use non-blocking I/O (e.g O_NONBLOCK
) you should use some multiplexing syscall (like .e.g. poll(2) or the older and obsolete select(2)
) to ensure that your socket is indeed readable or writable (i.e. will succeed on read(2) or recv(2) when readable, or on write(2) or send(2) when writable).
Of course, you'll need to multiplex several sockets if you have more than one.
In short you need an event loop (you might use libraries providing one e.g. libevent or libev ...), or have your own around a multiplexing syscall like poll
....). And even with one single bidirectional socket, you need to multiplex its input and its output (both with blocking or non-blocking I/O).
Read some good book, e.g. Advanced Linux Programming and some Linux Socket Tutorial and the Unix Network Programming book.
Your question is not precise enough to be answered. You should give more code, or at least give the relevant strace
traces on the suspicious syscalls.
Upvotes: 1