TcpClient類異步接收數據

原文鏈接:https://blog.csdn.net/WuLex

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 獲取或設置一個值,它指示是否已建立連接。
Available 獲取已經從網絡接收且可供讀取的數據量。
Client 獲取或設置基礎 Socket。
Connected 獲取一個值,該值指示 Socket 的基礎 TcpClient 是否已連接到遠程主機。
ExclusiveAddressUse 獲取或設置 Boolean 值,指定 TcpClient 是否只允許一個客戶端使用端口。
LingerState 獲取或設置有關關聯的套接字的延遲狀態的信息。
NoDelay 獲取或設置一個值,該值在發送或接收緩衝區未滿時禁用延遲。
ReceiveBufferSize 獲取或設置接收緩衝區的大小。
ReceiveTimeout 獲取或設置在初始化一個讀取操作以後 TcpClient 等待接收數據的時間量。
SendBufferSize 獲取或設置發送緩衝區的大小。
SendTimeout 獲取或設置 TcpClient 等待發送操作成功完成的時間量。

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連接

在這裏插入圖片描述

TcpClient已經連接上,NetworkStream讀取

在這裏插入圖片描述

NetworkStream已經讀取完畢,取出數據

在這裏插入圖片描述

TcpClient發送數據流程

確保TcpClient已經連接的情況下執行

TcpClient線程

在這裏插入圖片描述

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);
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章