gpt4 book ai didi

c#检测tcp断开连接

转载 作者:太空狗 更新时间:2023-10-29 18:22:36 24 4
gpt4 key购买 nike

我有两个简单的应用程序:

  • 在特定 TCP 端口上等待客户端连接的服务器应用程序。然后听他说的话,发回一些反馈并断开该客户的连接。

  • 连接到服务器应用程序的表单应用程序,然后说一些东西,然后等待反馈并断开与服务器的连接,然后在表单中显示反馈。

尽管服务器应用程序似乎运行正常(我已经使用 Telnet 对其进行了测试并且我看到了反馈并且我看到在反馈后直接发生断开连接),但是表单应用程序似乎没有注意到断开连接从服务器。 (即使在服务器断开连接后,TcpClient.Connected 似乎仍然有效)

我的问题是:为什么 TcpClient.Connected 保持真实,我如何知道服务器是否/何时断开连接?

这是我的完整代码:

表格申请:

using System;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;
using System.Threading;

namespace Sender
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void sendButton_Click(object sender, EventArgs e)
{
TcpClient tcpClient = new TcpClient();
tcpClient.Connect(IPAddress.Parse("127.0.0.1"), 81);
responseLabel.Text = "waiting for response...";
responseLabel.Invalidate();

// write request
NetworkStream networkStream = tcpClient.GetStream();
byte[] buffer = (new ASCIIEncoding()).GetBytes("Hello World! ");
networkStream.Write(buffer, 0, buffer.Length);
networkStream.Flush();

// read response
Thread readThread = new Thread(new ParameterizedThreadStart(ReadResponse));
readThread.Start(tcpClient);
}

void ReadResponse(object arg)
{
TcpClient tcpClient = (TcpClient)arg;
StringBuilder stringBuilder = new StringBuilder();
NetworkStream networkStream = tcpClient.GetStream();
bool timeout = false;
DateTime lastActivity = DateTime.Now;
while (tcpClient.Connected && !timeout)
{
if (networkStream.DataAvailable)
{
lastActivity = DateTime.Now;
while (networkStream.DataAvailable)
{
byte[] incomingBuffer = new byte[1024];
networkStream.Read(incomingBuffer, 0, 1024);
char[] receivedChars = new char[1024];
(new ASCIIEncoding()).GetDecoder().GetChars(incomingBuffer, 0, 1024, receivedChars, 0);
stringBuilder.Append(receivedChars);
}
}
else
{
if (DateTime.Now > lastActivity.AddSeconds(60))
timeout = true;
}
System.Threading.Thread.Sleep(50);
}
Invoke((MethodInvoker)delegate
{
responseLabel.Text = "Response from Listener:\n" + stringBuilder.ToString();
responseLabel.Invalidate();
});

if (timeout)
{
Console.Write("A timeout occured\n");
networkStream.Close();
tcpClient.Close();
}
}

}
}

服务器应用程序:

using System.Net;
using System.Net.Sockets;
using System.Text;
using System;
using System.Threading;

namespace Listener
{
class Program
{
static void Main(string[] args)
{
var tcpListener = new TcpListener(IPAddress.Any, 81);
tcpListener.Start();
Thread clientThread = new Thread(new ParameterizedThreadStart(Listen));
clientThread.Start(tcpListener);
}

static void Listen(object arg)
{
TcpListener tcpListener = (TcpListener)arg;
while (true)
{
TcpClient tcpClient = tcpListener.AcceptTcpClient();
Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClient));
clientThread.Start(tcpClient);
}
}

static void HandleClient(object arg)
{
TcpClient tcpClient = (TcpClient)arg;
StringBuilder stringBuilder = new StringBuilder();
ASCIIEncoding encoder = new ASCIIEncoding();
DateTime lastActivity = DateTime.Now;

// read request
NetworkStream networkStream = tcpClient.GetStream();
int timeout = 5; // gives client some time to send data after connecting
while (DateTime.Now < lastActivity.AddSeconds(timeout) && stringBuilder.Length==0)
{
if (!networkStream.DataAvailable)
{
System.Threading.Thread.Sleep(50);
}
else
{
while (networkStream.DataAvailable)
{
lastActivity = DateTime.Now;
byte[] incomingBuffer = new byte[1024];
networkStream.Read(incomingBuffer, 0, 1024);
char[] receivedChars = new char[1024];
encoder.GetDecoder().GetChars(incomingBuffer, 0, 1024, receivedChars, 0);
stringBuilder.Append(receivedChars);
}
}
}
string request = stringBuilder.ToString();

// write response
string response = "The listener just received: " + request;
byte[] outgoingBuffer = encoder.GetBytes(response);
networkStream.Write(outgoingBuffer, 0, outgoingBuffer.Length);
networkStream.Flush();

networkStream.Close();
tcpClient.Close();
}
}

}

最佳答案

当连接关闭时,TcpClient/NetworkStream 不会收到通知。您唯一可用的选择是在写入流时捕获异常。

几年前,我们开始使用套接字而不是 tcp 客户端。与 tcpclient 相比,socket 更有用。

有几种方法可以使用

投票是其中之一

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.poll.aspx

您还可以检查 Write 本身的结果。它为您提供了实际写入的字节数。

Connected 属性本身仅反射(reflect)上次操作时的状态。它的文档指出“Connected 属性的值反射(reflect)了最近操作的连接状态。如果您需要确定连接的当前状态,请进行非阻塞、零字节的 Send 调用。如果调用成功返回或抛出 WAEWOULDBLOCK 错误代码 (10035),则套接字仍处于连接状态;否则,套接字不再连接。"

http://msdn.microsoft.com/en-us/library/system.net.sockets.socket.connected.aspx

关于c#检测tcp断开连接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15067014/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com