当前位置: 首页 > 知识库问答 >
问题:

TCP客户端在被服务器断开之前一直处于停滞状态

邹嘉荣
2023-03-14
print("TCP -> Data received:\n" + file + "\n\n" + totalrecbytes + " Bytes");
while ((recBytes = netstream.Read(bytes, 0, bytes.Length)) > 0)
print("TCP -> Data received:\n" + file + "\n\n" + totalrecbytes + " Bytes");
private Thread _tcpThread;
private TcpClient _socketConnection;

public void Connect()
{
    try
    {
        _tcpThread = new Thread(ReciveDataClient);
        _tcpThread.IsBackground = true;
        _tcpThread.Start();
    }
    catch (Exception e)
    {
        print(e.Message);
    }
}

private void ReciveDataClient()
{
    try
    {
        _socketConnection = new TcpClient("xxx.xxx.xxx.xxx", 54321);
        print(this, "TCP -> Connection Success!");
    }
    catch (Exception e)
    {
        print("connection error: " + e.Message)
        return;
    }

    try
    {
        var bytes = new byte[BUFFER_SIZE];

        while (_socketConnection.Connected)
        {
            if (_socketConnection.Available <= 0) continue;

            // Get a stream object for reading              
            var netstream = _socketConnection.GetStream();

            int totalrecbytes = 0;

            int recBytes;
            string file = "";

            // Read incomming stream into byte arrary.                  
            while ((recBytes = netstream.Read(bytes, 0, bytes.Length)) > 0)
            {
                var incommingData = new byte[recBytes];
                Array.Copy(bytes, 0, incommingData, 0, recBytes);
                // Convert byte array to string message.                        
                var serverMessage = Encoding.ASCII.GetString(incommingData);
                file += serverMessage;
                totalrecbytes += recBytes;
            }

            print("TCP -> Data received:\n" + file + "\n\n" + totalrecbytes + " Bytes");

            netstream.Close();
        }

        print("TCP -> connection was terminated by the server");
    }
    catch (Exception e)
    {
        print(e.Message)
        return;
    }
}

到目前为止,我能找到的唯一解决办法是在发送数据后总是断开与服务器端的连接,并且在我的代码中,将整个receivedataclient包装在一个while循环中,类似于

private void ReciveDataClient()
{
    while (true)
    {
        try
        {
            _socketConnection = new TcpClient(_server.ToString(), _server.Port);

            //...

以便在服务器发送一些数据并断开客户端连接后立即启动新的连接。

共有1个答案

秦英发
2023-03-14

多亏了达米恩这个不信的人和身临其境的人的帮助,我才弄明白了这一点。经常阅读文档确实很有帮助,特别是当您是第一次使用时^^

networkstream.read是一个阻塞调用,如文档所述

返回:从NetworkStream读取的字节数,如果套接字已关闭,则返回0。

private Thread _tcpThread;
private TcpClient _socketConnection;

public void Connect()
{
    if(_socketConnection != null) return;

    try
    {
        _tcpThread = new Thread(ReciveDataClient);
        _tcpThread.IsBackground = true;
        _tcpThread.Start();
    }
    catch (Exception e)
    {
        print("TCP -> Thread error: " + e.Message);
    }
}

public void Disconnect()
{
    if(_socketConnection = null) return;

    _tcpThread.Abort();
}

private void ReciveDataClient()
{
    try
    {
        _socketConnection = new TcpClient("xxx.xxx.xxx.xxx", 54321);
        print(this, "TCP -> Connection Success!");
    }
    catch (Exception e)
    {
        print("TCP -> connection error: " + e.Message)
        return;
    }

    try
    {
        while(true)
        {
            // Get a stream object for reading              
            var netstream = _socketConnection.GetStream();

            //Check if still connected                
            if(_socketConnection.Client.Poll(0, SelectMode.SelectRead))
            {
                byte[] buff = new byte[1];
                if( _socketConnection.Client.Receive( buff, SocketFlags.Peek ) == 0 )
                {
                    // Server disconnected or connection lost
                    break;
                }
            }

            // Check to see if this NetworkStream is readable.
            if(myNetworkStream.CanRead)
            {
                byte[] myReadBuffer = new byte[BUFFER_SIZE];
                StringBuilder myCompleteMessage = new StringBuilder();
                int numberOfBytesRead = 0;
                int totalBytesReceived = 0;

                // Incoming message may be larger than the buffer size.
                do
                {
                    numberOfBytesRead = myNetworkStream.Read(myReadBuffer, 0, myReadBuffer.Length);
                    myCompleteMessage.AppendFormat("{0}", Encoding.ASCII.GetString(myReadBuffer, 0, numberOfBytesRead));    
                    totalBytesReceived += numberOfBytesRead;        
                }
                while(myNetworkStream.DataAvailable);

                // Print out the received message to the console.
                print("TCP -> Data received:\n" + myCompleteMessage.ToString() + "\n\n" + totalrecbytes + " Bytes");
            }
            else
            {
                //Prevent a direct loop
                Thread.Sleep(100);
            }          
        }

        print("TCP -> connection was terminated by the server");
    }
    catch(ThreadAbortException)
    {
        print("TCP -> Disconnected");
    }
    catch(Exception e)
    {
        print(e.Message)
    }

    // Clean up
    _socketConnection?.Close();
    _socketConnection?.Dispose();
    _socketConnection = null;
}
 类似资料:
  • 当TCP客户端与TCP服务器建立TCP连接时,需要先发送SYN,然后发送ACK,而TCP服务器只发送SYN/ACK,这两者是不同的

  • 我正在用Java编写一个简单的TCP客户机/服务器程序对,如果客户机在10秒内还没有发送任何东西,服务器必须断开连接。socket.setsoTimeout()使我得到了这一点,服务器就可以很好地断开连接。问题是--我如何让客户端确定服务器是否关闭?目前,我使用DataOutputStream向服务器写入数据,这里的一些答案表明,向封闭套接字写入数据将引发IOException,但这不会发生。 编

  • 创建 TCP 客户端 最简单的方法来创建一个 TCP 客户端,使用默认选项如下所示: NetClient client = vertx.createNetClient(); 配置 TCP 客户端 如果你不想使用默认值,则创建TCP 客户端时,通过传入NetClientOptions实例可以配置: NetClientOptions options = new NetClientOptions().s

  • 创建 TCP 服务器 使用最简单的方法来创建一个 TCP 服务器,使用所有默认选项如下所示: NetServer server = vertx.createNetServer(); 配置 TCP 服务器 如果你不想默认值,可以将服务器配置通过传入一个NetServerOptions实例来创建它: NetServerOptions options = new NetServerOptions().s

  • 在探索和实现Proact设计模式后,遇到了一个问题,即客户端(“C”客户端)连接在限制后不再接受。开始探索netty。这是我试图做的1。C客户端建立连接2。Java服务器接受连接并开始使用TCP向客户端发送8 Mb大小的字节缓冲区。有什么想法吗?netty是一个好的选择吗?我浏览了netty的一个很好的例子,不幸的是不走运。 先谢谢你。 尊敬的Ravi