代码之家  ›  专栏  ›  技术社区  ›  Ian Gleeson

c#通过tcp/ip处理的网络流

  •  1
  • Ian Gleeson  · 技术社区  · 7 年前

    我希望有人能告诉我为什么我的tcpListener/tcpClient代码中会出现对象处理异常。

    在acceptConnections和connectToServer方法中,我使用keepalive方法来告诉我何时断开连接,并且工作正常。

    然而,如果我取消对sendMsg方法的for循环的注释,我将在服务器上得到一个ObjectDisposedException,在客户端得到一个IOException。

    TCP客户端。SendMsg中的getStream()的NetworkStream似乎是问题所在,但我不确定为什么它会得到一个已处理的流。我需要2个线程才能使用它吗?

    static void Main(string[] args)
    {
        server.Listen();
        server.AcceptConnections();
    
        client.ConnectToServer();
    
        //for (int i = 0; i < 5; i++) {
        //    Thread.Sleep(3000);
        //    server.SendMsg("SENT MSG");
        //}
    
        Console.ReadLine();
    }
    
    public async void SendMsg(String message) {
            try {
                NetworkStream networkStream = tcpClient.GetStream();
                using (var writer = new StreamWriter(networkStream)) {
                    await writer.WriteLineAsync(message);
                    Console.WriteLine("msg sent");
                };
            } catch (Exception e) {
            }
    
        }
    
    private async void KeepAlive(TcpClient tcpClient) {
            bool clientConnected = true;
            using (NetworkStream networkStream = tcpClient.GetStream())
            using (var reader = new StreamReader(networkStream))
            using (var writer = new StreamWriter(networkStream)) {
                writer.AutoFlush = true;
                char keepalive = '0';
                while (clientConnected) {
                    try {
                        await writer.WriteLineAsync(keepalive);
                        string dataFromClient = await reader.ReadLineAsync();
                        Console.WriteLine("Server: " + dataFromClient);
                        Thread.Sleep(500);
                    } catch (IOException e){
    
                    } catch(ObjectDisposedException e) {
                        clientConnected = false;
                        clientsConnected--;
                    } catch (Exception e){
                    }
                }
            }
        }
    

    编辑:同时发布我的AcceptConnections方法

    public async void AcceptConnections() {
            while (true) {
                while (clientsConnected <= maxConnections) {
                    try {
                        tcpClient = await tcpListener.AcceptTcpClientAsync();
                        KeepAlive(tcpClient);
                    } catch (Exception e) {
                        Console.WriteLine("TOP EXCEPTION :: " + e);
                    }
                    clientsConnected++;
                    Console.WriteLine("SERVER Clients connected: " + clientsConnected);
                }
            }
        }
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Marc Gravell    7 年前

    你的 SendMsg 方法使用 using 在上 StreamWriter . 这个 违约 对于 StreamWriter 是级联dispose,因此这将关闭 NetworkStream . 如果这不是你的意图,你需要通过 leaveOpen: true constructor overload .

    坦率地说,没有理由使用 StreamWriter 这里-我建议处理 Stream Encoding 直接使用API。的一个优点 StreamWriter 在内部,它可能会为 byte[] 工作,但如果你只是为了一个目的而使用它,那么这种“优势”是没有意义的 Write 在处理之前,可以使用缓冲池轻松实现。