【发布时间】:2020-07-26 12:51:34
【问题描述】:
所以我的作业是使用tcp数据包编写一个POP3消息传递软件,并且不允许使用外部库。当我按下连接按钮时,我启动了 tcp 连接,并且我还有一个断开连接按钮来停止它。我用 PuTTY 测试了我的服务器程序,它在第一次连接后运行良好,但是当我再次按下断开连接并连接时,它不会将接收到的数据打印到显示器上。这个问题困扰了我很久,请帮忙。这是我的代码:
编辑: 问题是我不太了解线程是如何工作的,而且我没有为每个连接创建一个新线程,所以我每次创建一个新的监听器时都会实例化一个新线程。
namespace POP3Server
{
public partial class MainWindow : Window
{
private TcpListener server;
private Int32 port;
private IPAddress ipAddress;
private TcpClient client;
private Logger log;
private Thread tcpAcceptThread;
private bool serverStarted;
public MainWindow()
{
InitializeComponent();
log = new Logger(txtConsole);
serverStarted = false;
tcpAcceptThread = new Thread(GetData);
}
private void btnConnect_Click(object sender, RoutedEventArgs e)
{
try
{
port = Convert.ToInt32(txtPort.Text);
ipAddress = IPAddress.Parse(txtIP.Text);
server = new TcpListener(ipAddress, port);
server.Start();
if (tcpAcceptThread.ThreadState != ThreadState.Unstarted)
tcpAcceptThread.Start();
serverStarted = true;
log.WriteLine("Server started!");
btnConnect.IsEnabled = false;
btnDisconnect.IsEnabled = true;
}
catch (Exception ex)
{
log.WriteLine(ex.ToString());
}
}
private void btnDisconnect_Click(object sender, RoutedEventArgs e)
{
try
{
if (client != null)
client.Close();
server.Stop();
log.WriteLine("Server stopped!");
serverStarted = false;
btnConnect.IsEnabled = true;
btnDisconnect.IsEnabled = false;
}
catch (Exception ex)
{
log.WriteLine(ex.ToString());
}
}
private void GetData()
{
try
{
while (serverStarted)
{
client = server.AcceptTcpClient();
this.Dispatcher.Invoke(() => log.WriteLine("Connected!"));
Byte[] bytes = new Byte[256];
String data = null;
NetworkStream stream = client.GetStream();
int i;
// Loop to receive all the data sent by the client.
while ((i = stream.Read(bytes, 0, bytes.Length)) != 0)
{
// Translate data bytes to a ASCII string.
data = System.Text.Encoding.ASCII.GetString(bytes, 0, i);
this.Dispatcher.Invoke(() => log.WriteLine("Received: " + data));
}
}
}
catch (Exception ex)
{
this.Dispatcher.Invoke(() => log.WriteLine(ex.ToString()));
}
}
private void btnClear_Click(object sender, RoutedEventArgs e)
{
log.Clear();
}
}
}
【问题讨论】:
-
Hi Zoltán 欢迎.. 考虑 process 请求并在您的服务器读取循环之后使用(某事)answer,然后将您的 client.Close( ) 之后,而不是在按钮断开连接.. 您现在为每个命令创建一个新的服务器端客户端,而不终止它。
-
到目前为止,您为调试问题做了哪些工作?你的调查揭示了什么?我觉得这个问题太宽泛了,因为代码中有很多元素看起来有问题,而且没有足够的上下文来说明您需要帮助的具体问题。也就是说,最大的问题之一是您似乎错误地认为您可以重用
Thread对象。你不能。如果要为每个连接指定一个线程,则每次重新连接时都需要创建一个新线程。 -
@PeterDuniho 我意识到我需要更深入地挖掘以了解更多关于线程的信息。正如你提到的,我为每个连接创建了一个新线程,它解决了这个问题,但现在它在 GetData() 函数中抛出了一个 SocketException。我猜问题是我从另一个线程关闭了 tcp 侦听器,我不知道如何正确关闭它。
标签: c# sockets tcp server client