0

I have a problem, that I can not reproduce locally, but I can constantly reproduce on the server.

I have a TCP connection with the server and client. If I disconnect the client from the Wi-Fi TCP connection should be closed and the server should do some stuff upon disconnect. But I can not find any way from the server side to check if the connection is over. I implemented a heartbeat call, which runs each 5 seconds and sends a message to the client. I used SocketAsyncEventArgs for this. Looks something like this:


_socketAsyncEvent = new SocketAsyncEventArgs();
_socketAsyncEvent.Completed += OnSendCompleted;

public void SendHeartbeat() {

  byte[] message = ...;
  _socketAsyncEvent.SetBuffer(message, 0, message.Length);

  if (!_connection.Socket.SendAsync(_socketAsyncEvent))
  {
     OnSendCompleted(this, _socketAsyncEvent);
  }
}

protected void OnSendCompleted(object? sender, SocketAsyncEventArgs e)
{
   _socketAsyncEvent.SetBuffer(null, 0, 0);
}

I would assume, that it should throw ObjectDisposedException, as the doc says when The Socket has been closed.. But it does not. Well, docs say, that: Note that the successful completion of the SendAsync method does not indicate that the data was successfully delivered.... So SendAsync is not a solution.

I also tried such code: !(Socket.Poll(100, SelectMode.SelectRead) && Socket.Available == 0), but it also returns true, so I can not check with it too.

I also can not reproduce this behavior locally, because locally I can clearly see when receiving the answer BytesTransferred is 0, which means that the connection was closed. As the documentation says here. But it does not happen like this on the server.

The server is under Azure Load Balancer if this information changes something.

Any other thoughts, how can I understand from server-side, that the connection was closed?

Gitarani Sharma
  • 735
  • 3
  • 4
Anna Melashkina
  • 422
  • 2
  • 13
  • You are using a Keep-Alive. A Keep-Alive the client sends an empty TCP packet periodically so server doesn't close connection. Normally you set the client Keep-Alive at 5 seconds. Then at server you close connection if you do not see a packet from client every 10 seconds. The Keep-Alive is usually implemented in the library an not user code. The links you posted One is for Core 7 and the other for Net 4.8. A lot of changes were made between Net 4.8 and Core 7. Core was updated to allow Net library to run same on Windows and Linux. A lot of Windows bugs were fixed. – jdweng Nov 26 '22 at 15:32
  • Yes, sorry posted the wrong link. I'm using the lastest .net 7. – Anna Melashkina Nov 26 '22 at 15:34
  • You should use the real Keep-Alive and not implement you own. See https://learn.microsoft.com/en-us/dotnet/api/system.net.servicepoint.settcpkeepalive?view=net-7.0 – jdweng Nov 26 '22 at 15:50

0 Answers0