-
Notifications
You must be signed in to change notification settings - Fork 5.4k
Closed
Labels
area-System.Netbugos-linuxLinux OS (any supported distro)Linux OS (any supported distro)tenet-compatibilityIncompatibility with previous versions or .NET FrameworkIncompatibility with previous versions or .NET Framework
Milestone
Description
Hi,
We are experiencing an issue on Linux, building with publish -r linux-x64.
It looks like TcpListener.Stop() hangs when we try to orderly shutdown the server.
The socket is waiting for an Accept, then other thread does TcpListener.Stop().
The same code works fine on Windows (.NET Core) and also on Linux/Mono.
Here the sequence is:
- We start the server.
- We try to stop it.
- It takes forever to finish.
- Attaching the debugger (from Visual Studio on Windows, which is awesome :P) we see the process is stopped in TcpListener.Stop and never leaves.
Attached a repro case, but the code is super simple:
using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace tcplistenertest
{
class Program
{
static void Main(string[] args)
{
Thread listenerThread = StartBackgroundThread(new ThreadStart(ThreadProc));
while(Console.ReadLine() != string.Empty)
{
}
mListener.Stop();
listenerThread.Join();
}
static void ThreadProc()
{
try
{
mListener = StartListening();
AcceptLoop(mListener);
}
catch(Exception e)
{
Console.WriteLine($"ThreadProc error: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
}
}
static Thread StartBackgroundThread(ThreadStart task)
{
Thread thread = new Thread(task);
thread.IsBackground = true;
thread.Start();
return thread;
}
static TcpListener StartListening()
{
TcpListener result = new TcpListener(IPAddress.Any, PORT);
result.Start();
return result;
}
static void AcceptLoop(TcpListener listener)
{
// this is the main loop of the Socket based server
while (true)
{
Socket socket = null;
try
{
Console.WriteLine("Accepting connection...");
socket = AcceptConnection(listener);
Console.WriteLine($"Connection accepted from {socket.RemoteEndPoint}");
}
catch (SocketException e)
{
Console.WriteLine($"Socket error accepting connection: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
break;
}
catch (Exception e)
{
Console.WriteLine($"Generic error accepting connection: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
break;
}
try
{
socket.Close();
}
catch (Exception e)
{
Console.WriteLine($"Error closing socket: {e.Message}");
Console.WriteLine($"Stack trace:{Environment.NewLine}{e.StackTrace}");
break;
}
}
Console.WriteLine("Accept loop thread stopping");
}
static Socket AcceptConnection(TcpListener listener)
{
Socket socket = listener.AcceptSocket();
try
{
socket.SetSocketOption(SocketOptionLevel.Tcp, SocketOptionName.Debug, 1);
LingerOption optionValue = new LingerOption(true, 3);
socket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Linger, optionValue);
return socket;
}
catch (Exception)
{
socket.Close();
throw;
}
}
static TcpListener mListener;
const int PORT = 55000;
}
}Thanks!
pablo
[EDIT] Add C# syntax highlighting by @karelz
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area-System.Netbugos-linuxLinux OS (any supported distro)Linux OS (any supported distro)tenet-compatibilityIncompatibility with previous versions or .NET FrameworkIncompatibility with previous versions or .NET Framework