当客户端连接到TCPListener时,我一直收到以下异常。
例外:
System.ObjectDisposedException:无法访问已处置的对象。
对象名称:'System.Net.Sockets.NetworkStream'。
at System.Net.Sockets.NetworkStream.Read(Byte [] buffer,Int32 offset,Int32 size)
在Test.Server.ProcessClient(对象客户端,对象clientId)
Server.cs
public class Server
{
private TcpListener tcpListener;
private Thread listenThread;
public event EventHandler<EventLogArgs> EventLog;
public Server()
{
// Startup Code
ThreadPool.SetMinThreads(50, 50);
}
void UpdateEventLog(EventLogArgs e)
{
if (EventLog != null)
{
EventLog(this, e);
}
}
public void Start(string ip, int port_num)
{
Globals.listen = true;
Int32 port = port_num;
IPAddress address = IPAddress.Parse(ip);
this.tcpListener = new TcpListener(address, port);
Socket listenerSocket = this.tcpListener.Server;
LingerOption lingerOption = new LingerOption(true, 10);
listenerSocket.SetSocketOption(SocketOptionLevel.Socket,
SocketOptionName.Linger,
lingerOption);
this.listenThread = new Thread(ListenForClients);
this.listenThread.Start();
UpdateEventLog(new EventLogArgs("Started server..."));
}
public void Stop()
{
Globals.listen = false;
UpdateEventLog(new EventLogArgs("Stop server request sent..."));
}
private void ListenForClients()
{
this.tcpListener.Start();
while (Globals.listen)
{
if (!this.tcpListener.Pending())
{
// This is so we can stop the server.
Thread.Sleep(25); // choose a number (in milliseconds) that makes sense
continue; // skip to next iteration of loop
}
//blocks until a client has connected to the server
TcpClient client = this.tcpListener.AcceptTcpClient();
Globals.clientRequests++;
int clientRequest = Globals.clientRequests;
UpdateEventLog(new EventLogArgs("(" + Globals.clientRequests + ") Client connected...\r\n"));
ThreadPool.QueueUserWorkItem(o => ProcessClient(client, clientRequest));
}
UpdateEventLog(new EventLogArgs("Stopped server!"));
this.tcpListener.Stop();
}
private void ProcessClient(object client, object clientId)
{
TcpClient tcpClient = (TcpClient)client;
int clientRequestId = (int)clientId;
NetworkStream clientStream = tcpClient.GetStream();
byte[] clientRequestRaw = new byte[1024];
int bytesRead;
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Process client request..."));
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(clientRequestRaw, 0, 512);
}
catch
{
//a socket error has occured
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") SOCKET ERROR\r\n\r\n" + e));
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Client disconnected from server, nothing sent."));
break;
}
//message has successfully been received.
ASCIIEncoding encoder = new ASCIIEncoding();
string clientRequest = encoder.GetString(clientRequestRaw, 0, bytesRead);
string[] cmd;
string success;
Dictionary<string, string> headers = new Dictionary<string, string>();
Dictionary<string, string> contents = new Dictionary<string, string>();
if (clientRequest.Length == 0)
{
return;
}
// Parse HTTP request
Parse Parse = new Parse();
Parse.HTTPRequest(clientRequest, out success, out cmd, out headers, out contents);
string response;
if (success == "TRUE")
{
response = "HTTP/1.1 200 OK\r\n\r\nHello World!\r\n";
}
else
{
response = "HTTP/1.1 200 OK\r\n\r\nHello Error!\r\n";
}
ResponseToClient(client, response);
clientStream.Close();
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Server response...\r\n\r\n" + response));
}
tcpClient.Close();
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Client disconnected."));
}
private void ResponseToClient(object client, string response)
{
TcpClient tcpClient = (TcpClient)client;
NetworkStream clientStream = tcpClient.GetStream();
ASCIIEncoding encoder = new ASCIIEncoding();
byte[] buffer = encoder.GetBytes(response);
clientStream.Write(buffer, 0, buffer.Length);
clientStream.Flush();
}
}
Server类是从主线程启动的,如下所示:
this.server = new Server();
this.server.EventLog += new EventHandler<EventLogArgs>(UpdateEventLog);
ThreadPool.QueueUserWorkItem(o => this.server.Start("127.0.0.1", 3000));
我在这里做错了什么?
答案 0 :(得分:1)
我从ProcessClient()
方法中取出了while循环,这似乎解决了这个问题。不管怎样,谢谢。
private void ProcessClient(object client, object clientId)
{
TcpClient tcpClient = (TcpClient)client;
int clientRequestId = (int)clientId;
NetworkStream clientStream = tcpClient.GetStream();
byte[] clientRequestRaw = new byte[1024];
int bytesRead;
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Process client request..."));
while (true)
{
bytesRead = 0;
try
{
//blocks until a client sends a message
bytesRead = clientStream.Read(clientRequestRaw, 0, 512);
}
catch (Exception e)
{
//a socket error has occured
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") SOCKET ERROR\r\n\r\n" + e));
break;
}
if (bytesRead == 0)
{
//the client has disconnected from the server
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Client disconnected from server, nothing sent."));
break;
}
//message has successfully been received.
ASCIIEncoding encoder = new ASCIIEncoding();
string clientRequest = encoder.GetString(clientRequestRaw, 0, bytesRead);
string[] cmd;
string success;
Dictionary<string, string> headers = new Dictionary<string, string>();
Dictionary<string, string> contents = new Dictionary<string, string>();
if (clientRequest.Length == 0)
{
return;
}
// Parse HTTP request
Parse Parse = new Parse();
Parse.HTTPRequest(clientRequest, out success, out cmd, out headers, out contents);
string response;
if (success == "TRUE")
{
response = "HTTP/1.1 200 OK\r\n\r\nHello World!\r\n";
}
else
{
response = "HTTP/1.1 200 OK\r\n\r\nHello Error!\r\n";
}
ResponseToClient(client, response);
clientStream.Close();
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Server response...\r\n\r\n" + response));
}
tcpClient.Close();
UpdateEventLog(new EventLogArgs("(" + clientRequestId + ") Client disconnected."));
}
答案 1 :(得分:0)
您必须为网络提供正确的服务 在运行中编写services.msc,然后找到您的服务。 YourService-&GT;属性 - &GT;登录 - &gt;以网络身份登录
答案 2 :(得分:0)
既然你解决了问题我就会给你两个提示:
首先,不要使用线程池使异步操作同步。这是浪费资源。请改用异步方法(BeginAccept / EndAccept等)。
接下来将您的班级分成多个班级。一个只负责服务器部件,一个只负责客户部件。它使您的代码更容易遵循(即使对您来说:))。
答案 3 :(得分:0)
无论如何不要使用if (success == "TRUE")
!