我是服务器套接字的新手,在尝试创建一个简单的应用程序时遇到了这个问题。我可以很好地连接到服务器应用程序,然后重新连接。但是当我第二次断开连接时出现错误。这是我的代码,希望有人能帮我理解原因。
private static TcpListener clientListener;
private static Socket clientSocket;
private static bool running = false;
private static Thread runThread;
static void Main(string[] args){
writeMsg(">> Server started");
waitForConnection();
}
private static void writeMsg(String msg){
Console.WriteLine(msg);
}
private static void run(){
while (running){
try{
byte[] prefBuffer = new byte[100];
int bufferSize = clientSocket.Receive(prefBuffer);
writeMsg(">> Data recieved from client");
for (int i = 0; i < bufferSize; i++){
Console.Write(Convert.ToChar(prefBuffer[i]));
}
}
catch{
writeMsg("Connection Lost");
running = false;
clientListener.Stop();
clientSocket.Close();
waitForConnection();
}
}
runThread.Abort();
}
private static void waitForConnection(){
//This is the where the error is created and it says...
//Cannot access disposed object.
clientListener = new TcpListener(IPAddress.Parse("111.111.111.111"), 7414);
clientListener.Start();
writeMsg(">> Listening for connections...");
try{
clientSocket = clientListener.AcceptSocket();
writeMsg(">> Connection established");
running = true;
startRunThread();
}
catch (Exception e){
writeMsg(String.Format(">> Connection failed\n Error: {0}", e.Message));
}
}
private static void startRunThread(){
runThread = new Thread(new ThreadStart(run));
runThread.Start();
}
如上面代码中的注释所示,即使我重新初始化它,也会收到错误消息,说我无法访问已处置的对象? 这是堆栈跟踪
at System.Net.Sockets.Socket.Listen(Int32 backlog)
在System.Net.Sockets.TcpListener.Start(Int32 backlog)
在System.Net.Sockets.TcpListener.Start()
在... \ Program.cs中的Server.Program.waitForConnection():第55行
答案 0 :(得分:0)
如果你想开始新的开始新线程来处理新连接,我认为错误是由running
的标志引起的。 running
是静态变量,它在线程之间共享。每次连接丢失时,您设置running
为false,但该线程将阻塞直到新连接,并且running
将再次变为true。旧线程不会关闭。你需要打破循环,但是你需要注意它,因为启动新线程和关闭线程是并发的,可能是第一个关闭线程并且新线程开始完成,这将关闭应用程序,因为在某个时候,有没有' t有效的线程运行。
private static void run(){
while (running){
try{
byte[] prefBuffer = new byte[100];
int bufferSize = clientSocket.Receive(prefBuffer);
writeMsg(">> Data recieved from client");
for (int i = 0; i < bufferSize; i++){
Console.Write(Convert.ToChar(prefBuffer[i]));
}
}
catch{
writeMsg("Connection Lost");
running = false;
clientListener.Stop();
clientSocket.Close();
waitForConnection();
break;
}
}
runThread.Abort();
}
如果您只想处理同一个运行线程中的连接,我认为该错误是由调用startRunThread()
两次引起的。你可以像这样修改。
static void Main(string[] args)
{
writeMsg(">> Server started");
waitForConnection(true);
}
private static void run()
{
while (running)
{
try
{
byte[] prefBuffer = new byte[100];
int bufferSize = clientSocket.Receive(prefBuffer);
if (bufferSize == 0)
{
throw new ApplicationException();
}
writeMsg(">> Data recieved from client");
for (int i = 0; i < bufferSize; i++)
{
Console.Write(Convert.ToChar(prefBuffer[i]));
}
}
catch
{
writeMsg("Connection Lost");
running = false;
clientSocket.Close();
clientListener.Stop();
waitForConnection(false);
}
}
runThread.Abort();
}
private static void waitForConnection(bool newThread)
{
//This is the where the error is created and it says...
//Cannot access disposed object.
clientListener = new TcpListener(IPAddress.Parse("127.0.0.1"), 9091);
clientListener.Start();
writeMsg(">> Listening for connections...");
try
{
clientSocket = clientListener.AcceptSocket();
writeMsg(">> Connection established");
running = true;
if (newThread)
{
startRunThread();
}
}
catch (Exception e)
{
writeMsg(String.Format(">> Connection failed\n Error: {0}", e.Message));
}
}
BTW:如果客户端关闭,clientSocket.Receive(prefBuffer)
将返回零,您需要处理这种情况。