3

我有几个关于完成 tcp 连接的问题。

  1. 客户端使用 Tcp 连接到我的服务器,在接受客户端后 listener.BeginAcceptTcpClient(ConnectionEstabilishedCallback, null);,我开始使用networkStream.BeginRead(....).
    当我等待消息时客户端断开连接会发生什么?(例如,它失去了电源、互联网等)
    我怎么知道它什么时候发生?

  2. 如果读取成功后,我做一些事情,然后调用networkStream.Close(); client.Close();客户端会看到什么?如何“优雅地”终止连接?

  3. 如果我正在等待读取(使用 BeginRead),然后(在不同的线程上)关闭同一个流,会发生什么?

编辑添加:我在客户端和服务器之间确实有一条乒乓消息。够了吗?如果我没有收到 ping,请终止我的 NetworkStream?肯定有更好的东西。

4

3 回答 3

2

1-如果客户端由于电缆拔出而断开连接,直到下一次读取或写入套接字时才会知道。还要注意 tcpClient.Connected 属性值不可靠,它的值取决于最后一次通信;因此,如果最后一次通信成功,则其值为 true,否则为 false。有关该检查的更多信息

2-如果您关闭网络流和客户端,这是客户端的正常终止。

3-我不知道,给它一个测试。

如果您知道由于拔掉电缆而导致连接丢失,那么要获得适当的 IsConnected 值,您必须注意在读取或写入 tcp 期间丢失的连接,因此您需要通过尝试访问 tcpclient 成员- 抓住它的运作....

使用此 IsConnected 属性检查 tcpClient 是否已连接:

public static bool IsConnected
{
    get
    {
        try
        {
            //return _tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected;

            if (_tcpClient != null && _tcpClient.Client != null && _tcpClient.Client.Connected)
            {

                /* As the documentation:
                    * When passing SelectMode.SelectRead as a parameter to the Poll method it will return 
                    * -either- true if Socket.Listen(Int32) has been called and a connection is pending;
                    * -or- true if data is available for reading; 
                    * -or- true if the connection has been closed, reset, or terminated; 
                    * otherwise, returns false
                    */

                // Detect if client disconnected
                if (_tcpClient.Client.Poll(0, SelectMode.SelectRead))
                {
                    byte[] buff = new byte[1];
                    if (_tcpClient.Client.Receive(buff, SocketFlags.Peek) == 0)
                    {
                        // Client disconnected
                        return false;
                    }
                    else
                    {
                        return true;
                    }
                }

                return true;
            }
            else
            {
                return false;
            }
        }
        catch
        {
            return false;
        }
    }
}
于 2011-06-23T14:06:53.187 回答
2

当我等待消息时客户端断开连接会发生什么?(例如,它失去了电源、互联网等) 我怎么知道它什么时候发生?

由于不同的断开原因,会发生不同的事情。

当您收到 0 个字节时,检测到正常断开连接socket.EndRead。其他停工SocketException将导致EndReadSend

如果读取成功后,我做一些事情,然后调用 networkStream.Close(); 客户端.关闭();客户会看到什么?如何“优雅地”终止连接?

关闭会优雅地做到这一点。

如果我正在等待读取(使用 BeginRead),然后(在不同的线程上)关闭同一个流,会发生什么?

你会得到一个例外。要么ObjectDisposedException(如果您处置客户)或IOException

于 2011-06-23T14:19:09.820 回答
-1
public class Example
{
    static NetworkStream stream;
    static TcpClient client;

    public static void Main(String[] args)

        String message = String.Empty;

        //TCP connection
 Recon: Console.WriteLine("Connecting...");
        Int32 port = 3333;
        try
        {
            client = new TcpClient("ip.ip.ip.ip", port); //Try to connect
        }
        catch
        {
            Console.WriteLine("Problem while connecting!");
            Thread.Sleep(10000); //Waiting 10s before reconnect
            goto Recon;
        }

        Console.WriteLine("Connection established!\n");

        stream = client.GetStream();

        while (true)
        {

            //Buffer
            byte[] received_bytes = new Byte[1024];
            message = "";

            Console.WriteLine("Waiting to receive message...\n");

            Int32 bytes = stream.Read(received_bytes, 0, received_bytes.Length);
            message = System.Text.Encoding.GetEncoding("iso-8859-1").GetString(received_bytes, 0, bytes);

            if (bytes == 0) //If connection abort while reading
            {
                Console.WriteLine("Connection failed!");

                //Recconecting
                goto Recon;
            }

            Console.WriteLine("Received message: " + message);
        }
    }
}
于 2011-06-23T13:22:06.137 回答