c# NetworkStream 通过 tcp/ip 配置

标签 c# tcp tcplistener networkstream objectdisposedexception

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

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

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

SendMsg 中的 tcpClient.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);
            }
        }
    }

最佳答案

您的SendMsg 方法在StreamWriter 上使用usingStreamWriter默认 是级联处理,因此这将关闭 NetworkStream。如果这不是您的意图,您需要将 leaveOpen: true 传递给 constructor overload .

但坦率地说,没有理由在这里使用 StreamWriter - 我建议直接处理 StreamEncoding API。 StreamWriter 的一个优点是在内部它可能会为 byte[] 工作重新使用一个缓冲区,但是如果你只是将它用于一个 Write 在处理它之前,并且可以很容易地通过缓冲池实现。

关于c# NetworkStream 通过 tcp/ip 配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48095486/

相关文章:

c# - 使用 MVC 3 Controller 的依赖注入(inject)的命令模式

c# - wpf等待动画加速ColorAnimation

c# - 使用 MVC 项目注册 Api Controller 路由

c# - 是否有 Excel 图表对象到 System.Windows.Forms.DataVisualization.Charting 转换器?

linux - 围绕疯狂的设备接口(interface)进行路由

c套接字: recv and send data simultaneously

multithreading - 如何管理 TCP 客户端读/写重叠问题?

c# - 套接字超时后删除任何待读取的数据

c# - 开源 C# 代理服务器 - 任何项目/示例?

c# - 如何通过http-header区分http和https