我的申请有问题, 我有一个TCPListener,让我们在端口14000上监听 关闭应用程序后,我可以在CMD上看到侦听器仍在侦听。 在应用程序的第二次运行中,按预期的那样,我无法在同一端口(14000)上启动侦听器,因为在第二次运行时,我将应用程序端口更改为15000,工作非常好,并且侦听器在关闭后已关闭应用程序正在关闭, 我假设第一次运行时,应用程序死后,端口14000上的第一个侦听器保持打开状态,而第二次运行时,应用程序关闭/很好地打开了端口15000上的侦听器,为什么会发生这种情况?我以为可能是关于端口14000的问题我已经切换了打开端口的顺序(首先打开了15000),发现15000保持打开状态,而14000(第二次运行)已正确关闭并打开,为什么在第一次运行听众没有被关闭? 我服务器的代码:
class Server : IDisposable
{
private const int TIMER_PERIOD = 60 * 1000; // ms
private string servePort;
private string serverIP;
byte[] DataReceived = new byte[1024];
Action<string> MssageReceiveCallback;
private bool isListening = false;
static Timer serverTimer = null;
private TcpListener _Server;
private Dictionary<int, TcpClient> clientsList = new Dictionary<int, TcpClient>();
private bool serverListening = true;
private static int ClientInstance = 0;
public Server(string _serverIP, string _serverPORT, Action<string> messageReceiveCallback)
{
serverIP = _serverIP;
servePort = _serverPORT;
MssageReceiveCallback = messageReceiveCallback;
// InitilizeServer();
}
private void InitilizeServer()
{
_Server = new TcpListener(IPAddress.Parse(serverIP), int.Parse(servePort));
// if (serverTimer == null)
// serverTimer = new Timer(new TimerCallback(OnTimerCallback), null, TIMER_PERIOD, TIMER_PERIOD);
Task.Run(() =>
{
try
{
_Server.Start();
while (_Server != null)
{
TcpClient tcpClient;
try
{
tcpClient = _Server.AcceptTcpClient();
}
catch
{
continue;
}
Task.Run(() =>
{
ClientInstance++;
int currentinstance = ClientInstance;
clientsList.Add(currentinstance, tcpClient);
try
{
while (tcpClient.Connected && serverListening)
{
if (tcpClient.GetStream().DataAvailable)
{
int actualBufferlength = tcpClient.GetStream().Read(DataReceived, 0, DataReceived.Length);
byte[] data = new byte[actualBufferlength];
Buffer.BlockCopy(DataReceived, 0, data, 0, actualBufferlength);
string asciiMessage = Encoding.ASCII.GetString(data);
MssageReceiveCallback(asciiMessage);
}
else
{
Thread.Sleep(5);
}
}
}
catch (Exception ex)
{
}
finally
{
clientsList[currentinstance].Close();
clientsList.Remove(currentinstance);
}
});
}
}
catch (Exception ex)
{
}
});
}
public void StartServer()
{
InitilizeServer();
isListening = true;
}
public void SendMessage(string msg)
{
byte[] data = ASCIIEncoding.ASCII.GetBytes(msg);
foreach (TcpClient client in clientsList.Values)
{
client.GetStream().Write(data, 0, data.Length);
}
}
public void Dispose()
{
serverListening = false;
foreach (var item in clientsList.Values)
{
if (item.Connected)
item.Close();
}
_Server.Server.Close();
}
}
更新: 我已经在TCPView中签入,以查看侦听器绑定到哪个应用程序并发现了以下内容:
似乎监听器可用于不存在的进程
答案 0 :(得分:1)
我认为这里最大的问题(我已经在注释中指出了其他问题)是TCP关闭需要网络通信,并且默认情况下会在一段时间内阻止套接字重用。 >
您需要使用的功能是Socket.SetSocketOption
,特别是ReuseAddress
选项。您应该能够通过Server
上的TcpListener
属性来进行操作。请注意,必须在实际开始侦听器之前 完成。
答案 1 :(得分:0)
您可以尝试放置:
_Server.Server =null;
关闭后。