TcpClient类异步接收数据

TcpClient为基于Socket构建的用来进行TCP通信的简单类,主要用于TCP客户端的编写,可以使用同步或者异步。发送接收数据用NetworkStream。很多东西摘录自MSDN

构造函数

名称 说明
TcpClient() 初始化 TcpClient 类的新实例。
TcpClient(AddressFamily) 使用指定的族初始化 TcpClient 类的新实例。
TcpClient(IPEndPoint) 初始化 TcpClient 类的新实例,并将其绑定到指定的本地终结点。
TcpClient(String, Int32) 初始化 TcpClient 类的新实例并连接到指定主机上的指定端口。

以上是摘自MSDN上的,其中AddressFamily指的是使用指定的协议族,例如IPv4或者IPv6
如果要指定本地端口,用IPEndPoint来进行绑定。

属性

TcpCient

名称 说明
Active 获取或设置一个值,该值指示是否已建立连接。
Client 获取或设置基础 Socket。
Connected 获取一个值,该值指示 TcpClient 的基础 Socket 是否已连接到远程主机。

NetworkStream

名称 说明
CanRead 获取一个值,该值指示 NetworkStream 是否支持读取
CanWrite 获取一个值,该值指示 NetworkStream 是否支持写入

主要方法

TcpClient

名称 说明
BeginConnect(IPAddress, Int32, AsyncCallback, Object) 开始一个对远程主机连接的异步请求。远程主机由 IPAddress 和端口号 (Int32) 指定。
Close() 释放此 TcpClient 实例,并请求关闭基础 TCP 连接。

NetworkStream

名称 说明
BeginRead(Byte[], Int32, Int32, AsyncCallback, Object) 从 NetworkStream 开始异步读取。
Close() 关闭当前流并释放与之关联的所有资源
BeginWrite(Byte[], Int32, Int32, AsyncCallback, Object) 开始向流异步写入

流程

TcpClient读取数据过程

TcpClient连接

Created with Raphaël 2.1.0 主线程 实例化TcpClient,可绑定本地端口 异步连接到目标IP和端口(BeginConnect) 结束

TcpClient已经连接上,NetworkStream读取

Created with Raphaël 2.1.0 TcpClient异步连接线程 还原TcpClient 获取NetworkStream NetworkStream可读 NetworkStream异步读取Buffer 异步结束 yes no

NetworkStream已经读取完毕,取出数据

Created with Raphaël 2.1.0 NetworkStream异步读取线程 还原异步读取Buffer 获取Buffer数据 下一次异步读取开启 异步读取结束

TcpClient发送数据流程

确保TcpClient已经连接的情况下执行

TcpClient线程

Created with Raphaël 2.1.0 TcpClient发送 取得NetworkStream 获得数据,异步发送BeginWrite 发送结束

NetworkStream异步发送线程

Created with Raphaël 2.1.0 NetworkStream异步发送 还原NetworkStream 结束发送

实例

TcpClient连接

private void TcpButton_Click(object sender, EventArgs e)
{
    if (TcpButton.Text == "TCP打开")
    {
        TcpButton.Text = "TCP关闭";
        IPEndPoint targetPoint = new IPEndPoint(TcpUdp.VerifyInputIP(IPTextBox.Text), TcpUdp.VerifyInputPort(TcpTargetPortTextBox.Text));
        int localTcpPort = Int32.Parse(TcpSourcePortTextBox.Text);
        if (localTcpPort > 0)
        {
            IPEndPoint localEP = new IPEndPoint(IPAddress.Parse("127.0.0.1"), localTcpPort);
            tcp = new TcpClient(localEP);

        }
        else
        {
            tcp = new TcpClient();
        }
        tcp.ReceiveTimeout = 10;
        //异步连接
        tcp.BeginConnect(IPAddress.Parse(IPTextBox.Text), TcpUdp.VerifyInputPort(TcpTargetPortTextBox.Text), Connected, tcp);
    }
    else
    {
        TcpButton.Text = "TCP打开";
        if ((tcp != null) && (tcp.Connected))
        {
            ns.Close();
            tcp.Close();
        }
        SetTcpPic(tcp.Connected);
        TcpIsOpen = tcp.Connected;
    }
}

NetworkStream异步读取

private void Connected(IAsyncResult iar)
{
    tcp = (TcpClient)iar.AsyncState;
    tcp.EndConnect(iar);
    //MessageBox.Show("connected");
    SetTcpPic(tcp.Connected);
    TcpIsOpen = tcp.Connected;
    if ((tcp != null) && (tcp.Connected))
    {
        ns = tcp.GetStream();

        StateObject state = new StateObject();
        state.client = tcp;
        NetworkStream stream = state.client.GetStream();
        if (stream.CanRead)
        {
            byte[] buffer = new byte[tcp.ReceiveBufferSize];
            stream.BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(AsyncReadCallBack), state);
        }
    }
}

NetworkStream读取处理

private void AsyncReadCallBack(IAsyncResult iar)
{
    StateObject state = (StateObject)iar.AsyncState;
    if ((state.client == null) || (!state.client.Connected)) return;
    int NumOfBytesRead;
    NetworkStream ns = state.client.GetStream();
    NumOfBytesRead = ns.EndRead(iar);
    if (NumOfBytesRead > 0)
    {
        byte[] buffer = new byte[NumOfBytesRead];
        Array.Copy(state.buffer, 0, buffer, 0, NumOfBytesRead);
        ReceiveAppend(buffer, TcpUdp.StringType.String);
        ns.BeginRead(state.buffer, 0, StateObject.BufferSize, new AsyncCallback(AsyncReadCallBack), state);
    }
    else
    {
        ns.Close();
        state.client.Close();
        ns = null;
        state = null;
    }
}

NetworkStream发送

if (TcpIsOpen)
{
    if (ns != null)
    {
        //ns.Write(buffer, 0, buffer.Length);
        ns.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(StreamWriteCallBack), ns);
    }
}
private void StreamWriteCallBack(IAsyncResult iar)
{
    NetworkStream ns = (NetworkStream)iar.AsyncState;
    ns.EndWrite(iar);
}

猜你喜欢

转载自blog.csdn.net/Tokeyman/article/details/51452430