unity3d socket TCP 异步连接数据

来源:互联网 发布:知乎 大龄剩女 相亲 编辑:程序博客网 时间:2024/05/21 00:55
using UnityEngine;
using System.Collections;
using System;
using System.Threading;
using System.Text;
using System.Net;
using System.Net.Sockets;
using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
public class StateObject 
{
    // Client socket.
    public Socket workSocket = null;
    // Size of receive buffer.
    public const int BufferSize = 1024;
    // Receive buffer.
    public byte[] buffer = new byte[BufferSize];
    // Received data string.
    public StringBuilder sb = new StringBuilder();
    public byte[] recieveDatas=new byte[]{};
}
public delegate void InceptData(byte[] getBytes,int getType);
public delegate void SocketOfConnect(int type);

public class TCPClient
{
    private byte [] buffer = new byte[1024];
    public  string TCPserverIP="192.168.1.1";
    public  int TCPserverPort=5000;
    public  Socket clientSocket;
    public InceptData recievet;
    public SocketOfConnect ConnectedAndWillLogin;
    private bool isFirst=true;
    public TCPClient ()
    {
        SocketConnect();
    }
    
      public  void SocketConnect()  
    {  
        Debug.Log("SocketConnecting");
        
        IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(TCPserverIP), TCPserverPort);  
         clientSocket = new Socket(AddressFamily.InterNetworkSocketType.StreamProtocolType.Tcp);  
        
        IAsyncResult result = clientSocket.BeginConnect (ipe,new AsyncCallback (connectCallback),clientSocket);

    }

    private void connectCallback(IAsyncResult asyncConnect)
    {
        Debug.Log("connectSuccess");
        //与socket建立连接成功,开启线程接受服务端数据。
        receive();
      
    }
     //向服务端发送数据包
    public void Send(byte[] sendbytes)
    {
        if(clientSocket==null)
            return;
        if(!clientSocket.Connected)
        {
            clientSocket.Close();
            return;
        }
        try
        {
            //向服务端异步发送这个字节数组
            IAsyncResult asyncSend = clientSocket.BeginSend (sendbytes,0,sendbytes.Length,SocketFlags.None,new AsyncCallback (sendCallback),clientSocket);

        }
        catch (Exception e)
        {
             Debug.Log("send message error: " + e );
        }
    }
    private void sendCallback (IAsyncResult asyncSend)
    {
        Debug.Log("send Message succesfull");
    }

    public void receive()
    {
        try
        {    
            StateObject so = new StateObject();
            so.workSocket = clientSocket;
            //第一次读取数据的总长度
            clientSocket.BeginReceive(so.buffer,0,prefixSize,0,new AsyncCallback(receivedCallback),so);
        }
        catch(Exception e)
        {
            Debug.Log(e.ToString());
            clientSocket.Close();
        }
    }
    public  int prefixSize = 4;
    public MemoryStream receiveData = new MemoryStream();
    private bool isPresix = true;
    public int curPrefix = 0;//需要读取的数据总长度
    public void receivedCallback(IAsyncResult ar)
    {
        try
        {
            StateObject so = (StateObject)ar.AsyncState;
            Socket client = so.workSocket;
            if(!client.Connected)
            {
                return;
            }

            int readSize = client.EndReceive (ar);

            //结束读取,返回已读取的缓冲区里的字节数组长度

            //将每次读取的数据,写入内存流里
            receiveData.Write(so.buffer,0,readSize);
            receiveData.Position = 0;
            //读取前置长度,只读取一次
            if((int)receiveData.Length >= prefixSize && isPresix)
            {
                byte[] presixBytes = new byte[prefixSize];
                receiveData.Read(presixBytes,0,prefixSize);
                Array.Reverse(presixBytes);
                curPrefix = BitConverter.ToInt32(so.buffer,0);
                curPrefix=curPrefix;
               
                isPresix = false;
            }
            if(receiveData.Length - (long)prefixSize-4 < (long)curPrefix)
            {
                //如果数据没有读取完毕,调整Position到最后,接着读取。
                receiveData.Position = receiveData.Length;
            }
            else
            {
                //如果内存流中的实际数字总长度符合要求,则说明数据已经全部读取完毕。
                //将position位置调整到第4个节点,开始准备读取数据。
                receiveData.Position = 0;
                //读取数据
                byte[] datas = new byte[curPrefix+8];
                receiveData.Read(datas,0,datas.Length);
                receiveDataLoad(datas);

            }
            client.BeginReceive(so.buffer,0,StateObject.BufferSize,0,new AsyncCallback(receivedCallback), so);
        }
        catch(Exception e)
        {
            Debug.LogError(e.ToString());
            //Closed();
        }
    }
    private void receiveDataLoad(byte[]  bytes)

    {

       //用于做数据处理,加解密,或者压缩于解压缩

       
       

         prefixSize = 4;
         receiveData=new MemoryStream();
         isPresix = true;
         curPrefix = 0;//需要读取的数据总长度
    }


    //关闭Socket
    public void Closed()
    {
        try
        {
            if(clientSocket != null && clientSocket.Connected)
            {
                clientSocket.Shutdown(SocketShutdown.Both);
                clientSocket.Close();
            }
            clientSocket = null;
        }
        catch (SystemException e)
        {
            Debug.Log(e);
            clientSocket.Close();
            clientSocket = null;
        } 
        
    }

}


0 0
原创粉丝点击