I have a general question regarding TCP-IP communication...
for the time being I try to create a small communication between an ATMega and a Raspberry Pi. I will transmit some data for example every 5 minutes (e.g. 100 byte) via TCP/IP Protocol.
Does it make sense to keep the connection open or shall I create a new connection for each dataset?
Thanks for your help...
webbolle
I would lean towards keeping the TCP connection open rather than opening a new one everytime.
Here are a few reasons. First, by using the same connection, you would save on not having to send TCP handshake message (SYN-based messages) and teardown messages (FIN-based messages). In your case, if you are going to transmit 100 bytes every 5 minutes, the overhead of SYN/FIN messages might be more than that. Second, if you already have the connection open, then you would save on time since there is no need to do the reconnection. Third, TCP might go to slow-start every time you start the connection -- should not be a problem with 100 bytes, but if you need to send more bytes, then with every new connection, TCP would start its send window with 1 MSS. But, if you reuse an existing connection, TCP would (probably) use the current window.
Also:
An open connection doesn't consume any resources (bandwith etc.) except for the ports it holds on both devices. Basically every TCP-connection that has been opened and not been closed is still open, save unintended disconnections etc.
For detecting those is also doesn't make a difference wether you keep open or reopen:
If the connection dropped out in the meantime you'll receive the more or less same error.
Related
Please bear the naivity of this question as I have close to no knowledge of networking. Please help me understand this thing more clearly.
Suppose, there is a river and people from both the ends needs to travel back and forth from one end to another. So a bridge can act as connection between both ends, Till the time, bridge is alive, The connection is said to be alive and travelling is possible. I want to know what does it mean to keep a TCP connection alive and what is exactly kept alive? As in case of river, bridge was kept alive.
Contrary to a bridge a TCP connection is not a physical thing but only a logical association between to ends. Data get delivered between the ends hop by hop through several intermediate systems. Single packets might get lost on the way or even the other end or some intermediate systems might crash so that connectivity is lost completely.
As long as regular data exchange is done between the ends such conditions can quickly be detected. If one end sends data the other has to acknowledge these - if the acknowledgement is missing the packet gets retransmitted. If data are still not acknowledged after retransmissions the connection is considered broken.
But the ends might not continuously exchange data. If the connection is idle (i.e. no data exchange) then it will not be detected that something got broken. TCP keep alive works around this problem by regularly exchanging packets on idle connections and expecting an acknowledgment. These are packets with no data payload since no data are there to be transmitted.
In both these end-points, some data (or state variables) needs to be associated with each connection which is necessary to execute TCP protocol. E.g., sender needs to remember sequence numbers, maintain copies of all sent/but not acknowledged packets. Receiver needs to track sequence numbers too, store copies of packets that are out of order, and reconstruct original stream from received packets. These state data structures are created (i.e., memory is allocated) when the connection is established, and are destroyed (memory is freed) when the connection is terminated (e.g., after exchanging FINs). This state is accociated with each open TCP socket. A good practice is not to have connections open forever without exchanging data (e.g., if one of the communication partners has crashed, it won't be able to do proper connection termination), so if the connection is idle for a long period (which i don't know exactly) it is reasonable that the socket is closed. The concept is known as "soft state", which basically means that each state (memory) has an expiration inactivity time untill it is deleted. If the socket is closed, then when new data has to be sent, new connection has to be established. Yes it does involve sending packets, but it has overhead of sending TCP packets without any payload for one RTT, before the first data is sent.
In theory TCP connection exists only on end-points of the connection. In practice, however, there are also many kinds of so called "middleboxes", which is a general name for network device that is not a router or a switch. These middleboxes sometimes also need to maintain state accociated with each TCP connections, so these keepalives will also refresh the state on these middleboxes.
But in both cases, these keepalives basically tell to reset inactivity timer associate with state for this connection.
I have been testing a program which has simple communication between two machines over a 1Gbps line. While running TCP communications over the line I occasionally receive write errors on the client side (due to a timeout) when the network is totally flooded (running at or close to 100% usage). This generally happens when I am running multiple instances of the same program going to different ports.
My question is, is it possible to get a write error but still receive the message on the server side. It appears that is what is happening, and I am not quite sure why. Could it be that the ACK coming back to the client is what is timing out?
Yes, that is possible. TCP does not guarantee you that data you sent successfully is received and that data that is sent unsuccessfully is not received. This problem is unsolvable. It is called the Generals Problem. There is always a way to loose messages/packets such that the sender comes to the wrong conclusion. TCP guarantees that the receiver receives the same stream of bytes that the sender sent, but possibly cut off at an arbitrary point.
This unreliability has performance reasons, too. TCP data is buffered on both hosts as well as on the network. Acknowledgement is delayed.
You have to live with this. If you make your scenario more concrete I can suggest some strategies of dealing with this.
send puts data into the TCP send buffer.
If the send buffer has no enough space, send will block util the data is completely or partly copied into the send buffer, or the designed timeout arrives.
Read timeout and write timeout is OK. You should check and process them. The way is restarting read/write operation after timeout. You also pay attention to other read/write error except timeout.
I'm not sure if this is the correct place to ask, so forgive me if it isn't.
I'm writing computer monitoring software that needs to connect to a server. The server may send out relatively urgent messages, such as sound or cancel an alarm, and the client may send out data about the computer, such as screenshots. The data that the client sends isn't too critical on timing, but shouldn't be more than a two minutes late.
It is essential to the software that portforwarding need not be set up, and it is assumed that the internet connection will be done through a wireless router that has NAT almost all the time.
My idea is to have a TCP connection initiated from the client, and use that to transfer data. Ideally, I would have no data being sent when it is not needed, but I believe this to be impossible. Would sending the equivalent of a ping every now and again keep the connection alive, and what sort of bandwidth would it use if this program was running all the time on the computer? In addition, would it be possible to reduce the header size for these keep-alives?
Before I start designing the communication and programming, is this plan for connection flawed? Are there better alternatives?
Thanks!
1) You do not need to send 'ping' data to keep the connection alive, the TCP stack does this automatically; one reason for sending 'ping' data would be to detect a connection close on the client side - typically you only find out something has gone wrong when you try and read/write from the socket. There may be a way to change various time-outs so you can detect this condition faster.
2) In general while TCP provides a stream-oriented error free channel, it makes no guarantees about timeliness, if you are using it on the internet it is even more unpredictable.
3) For applications such as this (I hope you are making it for ethical purposes) - I would tend to use TCP, since you don't want a situation where the client receives a packet to raise an alarm but misses that one that turns it off again.
If a TCP connection is established between two hosts (A & B), and lets say host A has sent 5 octets to host B, and then the host B crashes (due to unknown reason).
The host A will wait for acknowledgments, but on not getting them, will resend octets and also reduce the sender window size.
This will repeat couple times till the window size shrinks to zero because of packet loss. My question is, what will happen next?
In this case, TCP eventually times out waiting for the ack's and return an error to the application. The application have to read/recv from the TCP socket to learn about that error, a subsequent write/send call will fail as well. Up till the point that TCP determined that the connection is gone, write/send calls will not fail, they'll succeed as seen from the application or block if the socket buffer is full.
In the case your host B vanishes after it has sent its ACKs, host A will not learn about that until it sends something to B, which will eventually also time out, or result in an ICMP error. (Typically the first write/send call will not fail as TCP will not fail the connection immediately, and keep in mind that write/send calls does not wait for ACKs until they complete).
Note also that retransmission does not reduce the window size.
Please follow this link
now a very simple answer to your question in my view is, The connection will be timed out and will be closed. another possibility that exists is that some ICMP error might be generated due to due un-responsive machine.
Also, if the crashed machine is online again, then the procedure described in the link i just pasted above will be observed.
Depends on the OS implementation. In short it will wait for ACK and resend packets until it times out. Then your connection will be torn down. To see exactly what happens in Linux look here other OSes follow similar algorithm.
in your case, A FIN will be generated (by the surviving node) and connection will eventually migrate to CLOSED state. If you keep grep-ing for netstat output on the destination ip address, you will watch the migration from ESTABLISHED state to TIMED_WAIT and then finally disappear.
In your case, this will happen since TCP keeps a timer to get the ACK for the packet it has sent. This timer is not long enough so detection will happen pretty quickly.
However, if the machine B dies after A gets ACK and after that A doesn't send anything, then the above timer can't detect the same event, however another timer (calls idle timeout) will detect that condition and connection will close then. This timeout period is high by default. But normally this is not the case, machine A will try to send stuff in between and will detect the error condition in send path.
In short, TCP is smart enough to close the connection by itself (and let application know about it) except for one case (Idle timeout: which by default is very high).
cforfun
In normal cases, each side terminating its end of the connectivity by sending a special message with a FIN(finish) bit set.
The device receiving this FIN responds with an acknowledgement to the FIN to indicate that it has been received.
The connection as a whole is not considered terminated until both the devices complete the shut down procedure by sending an FIN and receiving an acknowledgement.
I am reading 《Internetworking with TCP/IP》 by Douglas Comer,and when talking about creating a tcp connection ,there is a problem:
Suppose an implementation of TCP use
initial sequence number 1 when it
creates a connection,Explain how a
system crash and restart can confuse a
remote system into believing that the
old connection remained open.
I can't figure out why,please help me,Thanks.
Consider why a connection may get duplicate sequence numbers normally.
Then consider how the receiving system would handle a packet with a "duplicate" sequence number (because the transmitting system started reusing sequence numbers in packets it is using try to re-establish a connection).
*Edit: *
OP says:
but when re-establish the connection,the transmitting system will send a segment with SYN code bit set(and the sequence number be set 1 of course),won't that(SYN code bit set) inform the receiving system it is a new connection trying to be established ?see wiki for Transmission_Control_Protocol,it says that "Only the first packet sent from each end should have this flag(SYN) set."
But packets get lost and delayed and arrive out of order. You can't simply say everything arriving after the packet with the SYN flag is new. Lets say some of the old packets are delayed and arrive after establishment of a new connection. How do you distinguish whether a packet with sequence number #10 is from the old connection or new one? The worse case scenario is that it's from the old connection and the receiving system accepts it as from the new connection. When the real new connection packet #10 arrives, it's ignored as an unnecessary retranmission. The stream is corrupted without any indication of it.
http://www.tcpipguide.com/free/t_TCPConnectionEstablishmentSequenceNumberSynchroniz.htm
... The problem with starting off each connection with a sequence number of 1 is that it introduces the possibility of segments from different connections getting mixed up. Suppose we established a TCP connection and sent a segment containing bytes 1 through 30. However, there was a problem with the internetwork that caused this segment to be delayed, and eventually, the TCP connection itself to be terminated. We then started up a new connection and again used a starting sequence number of 1. As soon as this new connection was started, however, the old segment with bytes labeled 1 to 30 showed up. The other device would erroneously think those bytes were part of the new connection.
... This is but one of several similar problems that can occur. ...
The other issue with a predictable initial sequence number, such as starting at 1 every time, is that the predictability presents a vulnerability:
A malicious person could write code to analyze ISNs and then predict the ISN of a subsequent TCP connection based on the ISNs used in earlier ones. This represents a security risk, which has been exploited in the past (such as in the case of the famous Mitnick attack). To defeat this, implementations now use a random number in their ISN selection process.
Mitnick attack - http://www.cas.mcmaster.ca/wiki/index.php/The_Mitnick_attack
It's far worse than that though anyway - being predictable with sequence numbers makes spoofing and injecting an order of magnitude easier
After restart, if the first TCP connection is towards the same remote system, and since the sequence number will again be 1 - consider what that will cause.