Home > Mobile >  Error after connection restored Socket C#
Error after connection restored Socket C#

Time:12-06

I am uploading a file to the server in chunks. If you break the connection between the client and the server for a while, and then restore, the server throws an error when trying to receive data from the client:

An attempt to establish a connection was unsuccessful because the desired response was not received from another computer within the required time, or an already established connection was terminated due to an incorrect response from an already connected computer

This happens in the following case: if I send another chunk to the server and waits for a response from the server, the server at this time processes the request, sends the response to the client and waits for the next request. If, after a request to the server, the connection is terminated, and after 15 seconds, it is restored, an error appears.

Chunk sending code from the client:

chunk = reader.ReadBytes(chunkSize);
bytesToRead -= chunkSize;

var packet = packetService.CreatePacket(new ServerPacket
{
  Command = CommandsNames.UploadDataCommand,
  ClientId = clientId,
  Payload = uploadingService.GetUploadDataPayload(
    chunk,
    uploadingHash),
  PayloadParts = new List<int>
    {
      Encoding.Unicode.GetByteCount(uploadingHash),
        chunk.Length
    }
});

await dataTransitService.SendDataAsync(_socket, packet);
var response = await dataTransitService
   .ReadDataAsync(
     _socket,
     chunkSize,
     p => packetService.ParsePacket(p));

SendDataAsync method:

public async Task SendDataAsync(
            Socket socket, 
            IEnumerable<byte> data)
        {
            if (data != null && data.Any())
            {
                await socket.SendAsync(
                    new ArraySegment<byte>(data.ToArray()),
                    SocketFlags.None);
            }
        }

ReadDataAsync method:

public async Task<T> ReadDataAsync<T>(
            Socket socket, 
            int chunkSize,
            Func<IEnumerable<byte>, T> parsePacket)
        {
            var data = new ArraySegment<byte>(new byte[chunkSize]);
            var receivedPacket = new List<byte>();

            do
            {
                var bytes = await socket.ReceiveAsync(data, SocketFlags.None);

                if (data.Array != null)
                {
                    receivedPacket.AddRange(data.Array);
                }
            }
            while (socket.Available > 0);

            return parsePacket(receivedPacket);
        }

Client Socket configuration:

var (port, address) = (
                    _configurationSection["port"],
                    _configurationSection["address"]);

            var ipPoint = new IPEndPoint(
                IPAddress.Parse(address),
                Int32.Parse(port));
            socket = new Socket(
                AddressFamily.InterNetwork, 
                SocketType.Stream, ProtocolType.Tcp);

Server socket configuration:

 var section = _configuration.GetSection("listener");
            var (address, port) = (section["address"], section["port"]);
            var listenSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            var ipPoint = new IPEndPoint(IPAddress.Parse(address), Int32.Parse(port));

            try
            {
                listenSocket.Bind(ipPoint);
                listenSocket.Listen(20);
               
                Console.WriteLine("Waiting for connections...");
             
                var socket = listenSocket.Accept();                
                await _serverProcess.ProcessAsync(socket, StopServer);

CodePudding user response:

If, after a request to the server, the connection is terminated, and after 15 seconds, it is restored, an error appears.

If you unplug the network cable, Windows tells sockets over that NIC that they're disconnected. Otherwise (say your cable is still plugged in, but a cable, switch or router in between ceases to function), you need to send or receive on that socket in order for it to detect it's been disconnected.

See How to check if a socket is connected/disconnected in C#?.

Once disconnected, a socket cannot be restored. You need to detect this status, start a new connection and tell your server that you want to continue a prior transmission. We don't know whether your protocol understands that.

Also: IEnumerable<byte> data, data.Any(), new ArraySegment<byte>(data.ToArray()) - why?

  • Related