我有一个基于指南构建的简单客户端/服务器聊天应用程序。在客户端应用程序中,有一个方法可以启动连接,然后是另一个正在寻找来自服务器的新消息的方法(在线程下运行)。这可以按预期工作,但是如果与服务器实例的连接失败(例如,如果我终止服务器),则客户端无法再重新连接,因为该对象
TcpClient clientSocket = new TcpClient();
是全局声明的,不能重新用于新的连接尝试,因为套接字是一个用途。如果它尝试重用它,我会得到一个例外,即远程主机已经关闭了这个套接字上的连接。
为了解决这个问题,我知道每次运行连接方法时都需要创建 clientSocket 对象的新实例,以避免在连接丢失事件后重新启动客户端。通过在连接方法而不是全局创建 clientSocket ,它工作正常,我可以通过在连接丢失后再次运行该方法重新连接,但是,我无法传递此特定对象实例(因为它是在我的方法而不是全局创建的 getMessage()监听器方法,所以它不能通过这个套接字进行交互。
根据我的理解,有两种可能的解决方案:
我反复重复使用相同的 clientSocket 实例 再次,通过断开连接并重新连接它。这不行,就像我一样 似乎没有能够正确断开它,我不断得到 我不能重新连接到活动套接字的例外(在...中 现实,已经断开,因为服务器被杀死了)。我可以 .Close()它,但是无法创建新实例。
或者我每次创建一个新的TcpClient clientSocket 实例 尝试连接如上所述,这似乎是方式 go,但我不能让我的getMessage方法看到并使用这个特定的 实例。如果我显然在getMessage中重新创建实例 因为该实例未连接而无法正常工作。
简而言之,我需要我的方法与在不同方法范围内创建的特定对象实例进行交互。或者允许我在代码中重用/重新创建相同套接字的任何其他解决方案。如果代码不清楚,我很乐意回答任何问题。
完整的客户代码:
public partial class Form1 : Form
{
TcpClient clientSocket = new TcpClient(); // im declaring this globally here, this way both methods can see it but i cannot reuse it after a connection loss
NetworkStream serverStream = default(NetworkStream);
string readData = null;
bool connect = true;
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
byte[] outStream = Encoding.ASCII.GetBytes(textBox2.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
}
//This method initiates the connection
public void button2_Click(object sender, EventArgs e)
{
// i COULD create the TcpClient clientSocket instance here instead, but this way getMessage() will not be able to see it
connect = true;
try {
string ip = ipBox.Text;
int port = Convert.ToInt32(portBox.Text);
readData = "Connected";
clientSocket.Connect(ip, port);
serverStream = clientSocket.GetStream();
byte[] outStream = Encoding.ASCII.GetBytes(textBox3.Text + "$");
serverStream.Write(outStream, 0, outStream.Length);
serverStream.Flush();
msg();
Thread ctThread = new Thread(getMessage);
ctThread.Start();
}
catch
{
MessageBox.Show("Connection failed, cannot reach host");
}
}
// This method is being ran under a thread to keep looking for messages
private void getMessage()
{
while (connect == true)
{
serverStream = clientSocket.GetStream();
int buffSize = 0;
byte[] inStream = new byte[10025];
buffSize = clientSocket.ReceiveBufferSize;
try
{
serverStream.Read(inStream, 0, buffSize);
}
catch
{
MessageBox.Show("Connection lost, server stopped responding");
connect = false;
}
string returndata = Encoding.ASCII.GetString(inStream);
readData = "" + returndata;
msg();
}
}
private void msg()
{
if (this.InvokeRequired)
this.Invoke(new MethodInvoker(msg));
else
textBox1.Text = textBox1.Text + Environment.NewLine + " >> " + readData;
}
private void Form1_Load(object sender, EventArgs e)
{
ipBox.Text = "xx.xx.xx.xx";
portBox.Text = "8888";
textBox3.Text = Environment.UserDomainName + "//" + Environment.UserName;
}
}
感谢任何帮助,我经历了无数的问题和文章,但无法找到答案。
答案 0 :(得分:0)