1

Other side has set closing connection after some time of inactivity. It sends FIN, ACK, but my program sent only ACK without FIN as it should based on this Wikipedia post. Basically I have the same problem as in this question.
I don't want solution which tries to send data and check if error occurs I am just curious if it is possible to automatically gracefully close connection also from C# as a reply to FIN, ACK from the other side.
This answer claims that it points to answer, but there is no answer from that person on the pointed page.

EDIT:
Some added information:
I connect as a client through TcpClient class like this:

var client = new TcpClient();
client.Connect(new IPAddress(new byte[] { 192, 168, 1, 112 }), 60000);

Connection is created with RS485/LAN converter. This converter has parameter which defines after how long inactivity it closes connection. This parameter can be set or not. I can't affect that.
Connection (without data, with timeout set to 30 s, client on 192.168.1.13 and converter on 192.168.1.14) looks like this:

11:13:06   192.168.1.13   192.168.1.14   SYN
11:13:06   192.168.1.14   192.168.1.13   SYN, ACK
11:13:06   192.168.1.13   192.168.1.14   ACK
11:13:36   192.168.1.14   192.168.1.13   FIN, ACK
11:13:36   192.168.1.13   192.168.1.14   ACK

As you can see, client doesn't sent FIN and I wait several minutes without communication.

Community
  • 1
  • 1
Artholl
  • 1,231
  • 1
  • 17
  • 35
  • Are we meant to guess what your code does? – spender Apr 28 '15 at 10:09
  • Things like ACK and FIN are part of the TCP protocol, but not something that you normally worry about or think about at the software level when using C# and Socket. All that is hidden and considered to be at a lower level than the calls you are making at the Socket level. – RenniePet Apr 28 '15 at 11:22
  • @spender I think that it doesn't have to do something with my code, because I don't care about sending `FIN` or `ACK` in my code, but I edited my question anyway. – Artholl Apr 28 '15 at 11:32
  • @RenniePet I agree with you. I really hoped that I don't want to care about these things in C# anymore, but it looks like something doesn't work here properly... Or I just don't know how to use it... – Artholl Apr 28 '15 at 11:38

2 Answers2

0

Are you the client or the server? The disconnect should always start from the client application, not the server. TCP has a known issue when both ends of a connection attempt to disconnect at the same time. You can end up with sockets that is half open / half close due to race conditions. To prevent this from occurring it is recommended that you start the disconnect from the client. Normally I recommend that a message get sent from client application to server application to stop. The client waits for and acknowledge message that stop has completed. The client then closes the socket and terminates application. The server waits for event that socket closed. Then server closes application.

jdweng
  • 28,546
  • 2
  • 13
  • 18
  • I edited my question. My application is client, but I am sure that it don't want to disconnect in the same time as the server. – Artholl Apr 28 '15 at 11:40
  • If you don't want the server to close then use KeppAlive method which will sent an empty packet every 5 seconds. – jdweng May 02 '15 at 18:12
0

Conceptually, a TCP connection is two half-duplex half-connections, one in each direction. What you appear to be doing is closing one half-connection and not the other — and that is perfectly fine as far as TCP is concerned.

In order to fully close the connection, you need to send FINs from both sides, by calling either close or shutdown on both the client and the server.

jch
  • 4,491
  • 16
  • 36
  • Yes I know that. I just wonder if there is some setting when I don't have to use `close` or `shutdown` explicitly, but the socket closes itself when `FIN` from the other side arrives, because I have no way how to be notified that other side closes connection. – Artholl Apr 28 '15 at 13:02
  • You are notified of the other side closing the connection by `read` returning an end-of-file indication. – jch Apr 28 '15 at 22:45
  • If you mean `NetworkStream.Read` than I think it is not very good solution, because if there is no data to read and the other side is still connected it basically blocks the thread until the other side closes its connection. – Artholl Apr 29 '15 at 07:40
  • "If the remote host shuts down the connection [...] the Read method completes immediately and return[s] zero bytes" – jch Apr 29 '15 at 11:25
  • 1
    Yes it is true and I verified that but as I wrote if there is no data to read and the connection is still active the `Read` method blocks my thread so basically I can check connection this way only if I know that the other side is already disconnected because otherwise it blocks my thread from executing some other code. – Artholl Apr 29 '15 at 12:15