views:

204

answers:

2

Hello All.

I tried to send/receive data by using TcpClient. I did two experiments and found something interesting.

I setup the TcpListener in a server in Japan and the TcpClient in UK. I kept sending 500 bytes to the TcpListener and when TcpListener sends 10KB back to the TcpClient. I kept this send/receive looping for 500 times in each experiment.

Experiment 1:

In every send/receive loop, I create a brand new TcpClient (the time ticks from just before the creation) and send/receive

Experiment 2:

For all loops, I only have one TcpClient, and it keeps the connection with TcpListener and do the send/receive for 500 times.

Result:

The average value of the time cost for one loop:

E1: 1.8 seconds, E2: 0.49 seconds.

I am quite surprised by this result. So keeping connection for constant send/receive can save that lots of time??? nearly 2/3 of the time.

Is this true???

Thanks

====new====

@Jon Skeet, @dbemerlin, Thanks for the reply. I guessed the Tcp handshakes take some time tool.

So I did Experiment 3.

I setup a HttpListener as the server and use a WebClient to send/receive, the data sizes are exactly the same. And every time I used a new WebClient to send/receive between UK and Japan.

The result is 0.86 (average from 500 times loop, i.e., send/receive).

I assume that WebClient / HttpLisener themselves are Tcp, right? How can they be faster than raw TcpClient/TcpListener in my experiments??

THanks again

+3  A: 

This isn't particularly surprising, but it's not the cost of creating the object - it's the cost of setting up a TCP connection, with handshakes etc.

If you can do a lot of work over a single connection, that's more efficient than setting up a new connection each time. To put it in real world terms, consider a phone conversation between two people.

Efficient scenario: you dial the number, they pick up, you talk, they reply, you talk, they reply etc.

Inefficient scenario: you dial the numebr, they pick up, you talk, they reply, you hang up. You then immediately dial the number again, they pick up, you talk, they reply, you hang up etc.

Imagine doing the latter in reality! You'd go crazy very quickly...

EDIT: By default, WebClient will leave a hanging connection open to the web server. If you force the connections to be reset (basically disable KeepAlive) then you'll see the slow behaviour again.

Jon Skeet
new experiment added. thanks
Jack
I don't see any property in WebClient for KeepAlive. Can I disable it and retry?
Jack
+1  A: 

Each TCP connection requires a handshake when it's created (afair three-way-handshake, not sure atm) meaning that even if no data is sent yet a package is sent to the target, another one is sent back and - if it's a three way handshake - a third one is sent to the target.

A package travels from UK to Japan in, let's assume, 100ms. This means that each "tcpClient.Connect()" requires 300ms without any data sent. Your normal send & receive consists of one package sent to the destination and another one back, requiring a total of 200ms. Shutdown (if it's a clean one) requires another 100ms.

This results in 600ms to send the message, compared to 200ms if you keep the connection up as you will then save the handshake and shutdown.

dbemerlin
new experiment added. thanks
Jack