Help with TCP (JAVA) [SOLVED]
need to send ~20 bytes really fast via TCP (over LAN)
Hello ,
I am new to network programming and in need of some help.
i am currently working on a realtime distributed raytracer
and having issues with TCP latency.
in order to render, i need one pc(master) to inform the others(slaves) to render , then wait for them to stream the picture (jpeg) back to the requesting pc.
this needs to be really fast so the rendering would be as fast as possible.
what I do is:
1. Starting handshake (TCP - roughly 20-30 bytes , I need to be sure that the slave knows the master is requesting him to do work + passing some camera data )
2. streaming the jpeg ( UDP - i dont care if a packet misses, or if packets arrive in order)
3. Closing handshake (TCP - 2 bytes ,both sides need to know they can move on)
performance:
-Running on LAN , stages 1,2,3 take about 200-400 miliseconds (i did not include actual time it took to render, just the network stuff)
-Running both Master and Slave on the same pc , 0-16 miliseconds
So i did some profiling , actual streaming of the jpeg took 0-15 miliseconds,
while doing simple handshake in TCP (sending 1byte then waiting to receive 1byte) took 170-240 miliseconds.
NOTES:
- I did (NOT) disabled Nagle's algorithm (this was the problem)
- I am doing a .flush() on stream after sending.
- Handshakes described above are done with messages, I am not opening then closing the connection.
i really need the TCP part to have reliable control of the communication, but performance are really bad even for really small data size.
if anyone has any experience with this kind of project , i would love to hear your thoughts\tips\insights...
[SOLVED]
this line was the problem
if(consts.TCP_NO_DELAY) tcpSocket.setTcpNoDelay(true);
BUT "consts.TCP_NO_DELAY" was set to false...
these kind of errors happen to me all too often :(
[Edited by - FlameAlpha on March 18, 2010 6:57:49 PM]
Are you doing a .flush() on stream after sending?
Opening/closing a connection is also not the best way. Connect once, then signal via messages.
Opening/closing a connection is also not the best way. Connect once, then signal via messages.
first of all , thanks for the response -
is it reasonable that sending one byte then waiting for response of one byte long, would take over 150ms?
Quote:Original post by Antheus
Are you doing a .flush() on stream after sending?
yes i am, forgot to mention it
Opening/closing a connection is also not the best way. Connect once, then signal via messages.
I am not opening/closing the connection, the "Handshakes" I was describing are done with messages
is it reasonable that sending one byte then waiting for response of one byte long, would take over 150ms?
Quote:Original post by FlameAlpha
is it reasonable that sending one byte then waiting for response of one byte long, would take over 150ms?
Maybe if it was 12 time zones away on a slow network, but it sounds high to me.
I made an MMO in Java and wrote a UDP wrapper for my networking code to gain the TCP-like reliability that I wanted. My development server is about 750 miles from me. I send a keep alive packet once a minute and it's 13 bytes + the UDP overhead and it only takes about ~35ms for the packet round trip.
I'm not sure if your latency is the additional TCP overhead, or perhaps something with your LAN? I used TCP in Java in the past, but I don't recall what the performance was like.
well... I will try avoiding implementing TCP using UDP (for now) , but at least i now know these performance are not reasonable, thanks for the response.
Some collected wisdom about high-performance TCP:
- You want to establish the TCP connection once (say, each slave agent connects to the master when it initially starts up).
- You want to push messages across this established TCP connection to each client when it's time.
- You want to turn off Nagling (TCP_NODELAY, 1) -- as you said, that was your main problem.
- You probably don't want to use UDP to stream the result back. Just send it on the TCP connection. Use select() or non-blocking sockets or async I/O or even a thread to send the data back over the socket.
- If your link has high latency compared to the bandwidth, you want to turn on window scaling. You do this by configuring a large buffer (say, 1 MB) on the socket after you create it but before you bind or connect it.
- You want to establish the TCP connection once (say, each slave agent connects to the master when it initially starts up).
- You want to push messages across this established TCP connection to each client when it's time.
- You want to turn off Nagling (TCP_NODELAY, 1) -- as you said, that was your main problem.
- You probably don't want to use UDP to stream the result back. Just send it on the TCP connection. Use select() or non-blocking sockets or async I/O or even a thread to send the data back over the socket.
- If your link has high latency compared to the bandwidth, you want to turn on window scaling. You do this by configuring a large buffer (say, 1 MB) on the socket after you create it but before you bind or connect it.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement