iT邦幫忙

0

c#的socket client實現和asyn read and write

  • 分享至 

  • xImage
  •  

client的實現:

public class socket_management : MonoBehaviour
{
    private TcpClient tcpClient_ = new TcpClient();
    public socket_management()
    {

    }
    /// 
    /// 建立 Connect Server.
    /// 
    public void Init()
    {
        tcpClient_.NoDelay = true;  //關閉Nagle演算法,這個算法是之前網路不發達的時候才需要的
        
        //初始化callback
        AsyncCallback connect_callback = null;
        // 實現callback,這個函數會在connect之後被調用;
        connect_callback = ar =>
        {
            tcpClient_.EndConnect(ar);//異步調用的時候需要的;
            if (tcpClient_.Connected)//判斷是否連接成功;
            {
                NetworkStream networkStream_connect = tcpClient_.GetStream();//初始化數據流
                byte[] tempRecvBuffer = new byte[1024];
                if (networkStream_connect.CanRead)
                {
                    //讀取數據;
                    //第4個參數是回調函數,也就是有讀到數據的時候,會被調用;
                    //最後一個參數是用來存儲數據,看下面的endReadCallback函數的參數,是IAsyncResult類型,這個可以用來存取讀到的數據,數據格式是在這個參數自定義的:new了一個object數組,這個object數組只有一個元素,用來接受數據的byte[],使用的時候,可以放入自定義的class structure 等,但是讀取的時候要注意排序;
                    networkStream_connect.BeginRead(tempRecvBuffer, 0, 1024, new  AsyncCallback(endReadCallback), new object[] { tempRecvBuffer });

                }
                if (networkStream_connect.CanWrite)
                {
                    //發送數據
                    byte[] buffer = Encoding.UTF8.GetBytes("hello Server");
                    Debug.Log("send msg" + buffer.Length);
                    networkStream_connect.BeginWrite(buffer, 0, buffer.Length, new AsyncCallback(endWriteCallback), null);
                }

            }
        };

        tcpClient_.BeginConnect(IPAddress.Parse("127.0.0.1"), 7001, new AsyncCallback(connect_callback), tcpClient_);
        Debug.Log("Init : connect to server");
    }
    ...
}

讀的回調函數:

private void endReadCallback(IAsyncResult ar)
    {
        NetworkStream networkStream = tcpClient_.GetStream();
        int packetLength = networkStream.EndRead(ar);
        if (packetLength > 0)
        {
            Debug.Log("get a msg " + packetLength);
            //獲取讀到的數據
            object[] objArr = (object[])ar.AsyncState;
            //因爲數組的0個元素是要讀的buffer
            byte[] recvBuffer = (byte[])objArr[0];
            
            Array.Resize(ref recvBuffer, packetLength);

            //transform to string and print,轉換成string類型,並進行打印
            string result = System.Text.Encoding.UTF8.GetString(recvBuffer);
            Debug.Log(result);
            
            //這一步一定要寫,才會繼續讀下去
            networkStream.BeginRead(recvBuffer, 0, recvBuffer.Length, new AsyncCallback(endReadCallback), new object[] { recvBuffer });
        }
    }

寫回調函數:


    private void endWriteCallback(IAsyncResult ar)
    {
        NetworkStream networkStream = tcpClient_.GetStream();
        networkStream.EndWrite(ar);
    }

效果演示:
用visual studio2019寫的c++server,收到什麽數據,就會回復什麽數據:
https://ithelp.ithome.com.tw/upload/images/20210804/20139212NV74ekfVW8.png
用unity和vscode寫的c#中client端,連上之後,會發一個'hello server',然後把收到的數據打印出來:
https://ithelp.ithome.com.tw/upload/images/20210804/201392121FA1mJ4wWn.png


圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言