首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >半闭TcpClient

半闭TcpClient
EN

Stack Overflow用户
提问于 2016-03-25 19:21:22
回答 1查看 963关注 0票数 2

我对半关闭TcpClient有严重的问题。我想做的是:

关于客户:

  1. 发消息
  2. 关闭基础套接字以发送
  3. 收到答复
  4. 关闭基础套接字以进行读取(或者,此时只需关闭它)

在服务器上:

  1. 收到一条消息
  2. 关闭基础套接字以读取
  3. 发送回复
  4. 关闭底层套接字以便写入(或者,此时只需关闭它)

但是,在客户机或服务器上的步骤2之后,我不能使用TcpClient的流。下面是我的代码的一个非常简化的版本(没有异步调用、处理和清理,也使用StreamReader和StreamWriter而不是XmlSerializer):

代码语言:javascript
复制
        //initialize the connection between the server and the client
        var listener = new TcpListener(IPAddress.Any, 13546);
        listener.Start();
        var client = new TcpClient("127.0.0.1", 13546);
        var server = listener.AcceptTcpClient();
        listener.Stop();

        //CLIENT: send the message
        var cwriter = new StreamWriter(client.GetStream());

        cwriter.Write("client's message");
        cwriter.Flush();

        client.Client.Shutdown(SocketShutdown.Send);

        //SERVER: receive the message
        string msg;
        var sreader = new StreamReader(server.GetStream());

        msg = sreader.ReadToEnd();

        server.Client.Shutdown(SocketShutdown.Receive);

        //SERVER: send a response
        //Here the code fails on server.GetStream() - 
        //InvalidOperationException, apparently the whole connection is closed now

        var swriter = new StreamWriter(server.GetStream());

        swriter.Write(msg + " with server's response");
        swriter.Flush();

        server.Client.Shutdown(SocketShutdown.Send);

        //CLIENT: receive the message
        var creader = new StreamReader(client.GetStream());

        var response = creader.ReadToEnd();

        client.Client.Shutdown(SocketShutdown.Receive);

有没有办法不使用原始套接字就做到这一点?我有什么地方不对劲吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-03-25 20:15:57

问题是ReadToEnd读取数据直到流的末尾。通过发出Client.Shutdown,您实际上关闭了套接字,从而无法重用它(至少在TCPClient的情况下是这样)。这是GetStream()的代码

代码语言:javascript
复制
public NetworkStream GetStream() {
    if(Logging.On)Logging.Enter(Logging.Sockets, this, "GetStream", "");
    if (m_CleanedUp){
        throw new ObjectDisposedException(this.GetType().FullName);        
    }
    if (!Client.Connected) {
        throw new InvalidOperationException(SR.GetString(SR.net_notconnected));
    }
    if (m_DataStream==null) {
        m_DataStream = new NetworkStream(Client, true);
    }
    if(Logging.On)Logging.Exit(Logging.Sockets, this, "GetStream", m_DataStream);
    return m_DataStream;
}

如您所见,错误发生是由于关闭套接字。

编辑:这是可笑的奇怪,但我想我找到了原因,为什么它不能正常工作。原因是Shutdown总是将整个套接字的标志设置为断开连接。即使我们实际上不是这样关闭它的!如果在方法开始时保留流,我们就不会面临这个问题,因为问题在于检查套接字状态的GetStream方法。但是,当其他代码检查套接字的状态时,我们可能会暴露在一些But中。

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

https://stackoverflow.com/questions/36226535

复制
相关文章

相似问题

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