首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TCPListener异常的帮助

TCPListener异常的帮助
EN

Stack Overflow用户
提问于 2010-12-13 14:11:43
回答 4查看 2K关注 0票数 1

当客户端连接到TCPListener时,我一直得到以下异常。

异常:

System.ObjectDisposedException:无法访问已释放的对象。

对象名称:‘System.Nets.ockets.NetworkStream’。

在System.Net.Sockets.NetworkStream.Read(Byte[]缓冲器,Int32偏移量,Int32大小)

在Test.Server.ProcessClient(对象客户端,对象clientId)

Server.cs

代码语言:javascript
复制
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();            
    }
}

服务器类是从主线程启动的,如:

代码语言:javascript
复制
this.server = new Server();
this.server.EventLog += new EventHandler<EventLogArgs>(UpdateEventLog);
ThreadPool.QueueUserWorkItem(o => this.server.Start("127.0.0.1", 3000));

我在这里做错什么了?

EN

回答 4

Stack Overflow用户

发布于 2010-12-13 14:25:33

我已经从ProcessClient()方法中取出了while循环,这似乎解决了这个问题。不管怎样,谢谢你。

代码语言:javascript
复制
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
EN

Stack Overflow用户

发布于 2010-12-13 14:18:30

你必须为网络提供正确的服务。

在运行中编写services.msc,然后找到您的服务。您的服务->属性->登录->登录为网络

票数 0
EN

Stack Overflow用户

发布于 2010-12-13 14:28:00

既然你解决了你的问题,我就给你两个提示:

首先,不要使用线程池进行异步同步操作。这是浪费资源。使用异步方法(BeginAccept/EndAccept等)。

接下来,将类划分为多个类。一个只负责服务器部件,另一个只负责客户端部分。它使您的代码更容易理解(甚至对于您:)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4429651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档