tcp发送图片流

发送端:

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System;

public class SendPhoto : MonoBehaviour
{

    private Socket socket = null;

    private IPEndPoint endPoint = null;

    // Use this for initialization
    void Start()
    {
        InitSocketEnv();       
    }

    // Update is called once per frame
    void Update()
    {
        if (Input.GetKeyDown(KeyCode.S))
        {
            SendMegEvent();
        }
    }

    public void SendMegEvent()
    {
        SendPhotoMessage("Texture003.jpg");
    }

    void SendPhotoMessage(string fileName)
    {
        //byte[] buffer = ReadImg(fileName); //null

        FileStream fs = new FileStream(Application.streamingAssetsPath + "/" + fileName, FileMode.OpenOrCreate, FileAccess.Read);
        BinaryReader strread = new BinaryReader(fs);
        byte[] byt = new byte[fs.Length];
        strread.Read(byt, 0, byt.Length - 1);

        //byte[] size = new byte[4];
        //size = BitConverter.GetBytes(byt.Length);

        socket.Send(byt);
        //socket.Send(size);
        print("已发送!");

        fs.Close();
        socket.Close();
    }

    byte[] ReadImg(string fileName)
    {
        FileInfo fileInfo = new FileInfo(Application.dataPath + "/" + fileName);
        byte[] buffer = new byte[fileInfo.Length];
        using (FileStream fs = fileInfo.OpenRead())
        {
            fs.Read(buffer, 0, buffer.Length);
        }

        return buffer;
    }

    void InitSocketEnv()
    {
        socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        endPoint = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8696);
        socket.Connect(endPoint);
    }

    void OnDestory()
    {
        socket.Close();
    }
}

接收端:

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using System;

public class RecivePhoto : MonoBehaviour
{
    private Socket m_socket = null;
    private IPEndPoint m_ipEp = null;

    private Thread m_thread = null;
    private bool isRunningThread = false;

    private Queue<byte[]> m_queue;

    // Use this for initialization
    void Start()
    {
        m_queue = new Queue<byte[]>();
        InitSocketEnv();
    }

    // Update is called once per frame
    void Update()
    {
        if (m_queue.Count > 0)
        {
            Debug.Log(m_queue.Count);

            byte[] temp = m_queue.Dequeue();

            FileStream fs = File.Create(Application.dataPath + "/" + "2.jpg");
            fs.Write(temp, 0, temp.Length);
            fs.Close();
        }


    }

    void ReciveMeg()
    {
        while (isRunningThread)
        {
            Socket socket = m_socket.Accept();

            //获取图片字节流长度
            //byte[] dataSize = new byte[4];
            //int rect = socket.Receive(dataSize, 0, 4, SocketFlags.None);
            //int size = BitConverter.ToInt32(dataSize, 0);

            //Debug.Log(size);

            byte[] buffer = new byte[2000000];
            socket.Receive(buffer, buffer.Length, SocketFlags.None);

            //byte[] bufferSize = new byte[4];
            //socket.Receive(bufferSize, 0, 4, SocketFlags.None);
            //int size = BitConverter.ToInt32(bufferSize, 0);
            //Debug.Log(size);

            m_queue.Enqueue(buffer);

            socket.Close();
        }

        Debug.Log("stop");
    }

    void InitSocketEnv()
    {
        m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        m_ipEp = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 8696);
        m_socket.Bind(m_ipEp);
        m_socket.Listen(5);

        isRunningThread = true;
        m_thread = new Thread(ReciveMeg);
        m_thread.Start();
    }

    void OnDistory()
    {
        isRunningThread = false;
        m_socket.Close();
    }
}

小插曲:
使用中出现了一些问题,就是只能发送一次,再发就报错了去掉下图中的Close也不行
在这里插入图片描述
耽误了好久
后来放进协程里这样写终于能用了
在这里插入图片描述

更新了脚本:

发送端:

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System;
using static GeIP;

public class SendPhoto : MonoBehaviour
{
    public static SendPhoto Instance;
    private Socket socket = null;

    private IPEndPoint endPoint = null;

    public XMLConfig netConfig;

    public string RemoteIp = "192.168.3.188";

    private void Awake()
    {
        Instance = this;
    }
    // Use this for initialization
    void Start()
    {
        //print("本机ip:IPV4_" + GeIP.IP(address.IPv4) + "     IPV6_" + GeIP.IP(address.IPv6));
        InitSocketEnv();
    }

    // Update is called once per frame
    void Update()
    {
        //if (Input.GetKeyDown(KeyCode.S))
        //{
        //    SendMegEvent();
        //}
    }


    public void SendMegEvent(byte[] Byte)
    {
        StartCoroutine(SendPhotoMessage(Byte));
    }

    IEnumerator SendPhotoMessage(byte[] Byte)
    {
        //byte[] buffer = ReadImg(fileName); //null

        //FileStream fs = new FileStream(Application.streamingAssetsPath + "/" + fileName, FileMode.OpenOrCreate, FileAccess.Read);
        //BinaryReader strread = new BinaryReader(fs);
        //byte[] byt = new byte[fs.Length];
        //strread.Read(byt, 0, byt.Length - 1);

        byte[] size = new byte[4];
        size = BitConverter.GetBytes(byt.Length);
        byte[] b = Byte;
        //print(Byte.Length.ToString());

        socket.Send(b);
        //socket.Send(size);
        //print("b已发送!");
        //PageManager.Instance.GameOver();
        yield return new WaitForEndOfFrame();

        System.GC.Collect();

        //显示UpLoading 界面



        fs.Close();
        //socket.Close();
        //yield return new WaitForEndOfFrame();
        //InitSocketEnv();
    }

    byte[] ReadImg(string fileName)
    {
        FileInfo fileInfo = new FileInfo(Application.dataPath + "/" + fileName);
        byte[] buffer = new byte[fileInfo.Length];
        using (FileStream fs = fileInfo.OpenRead())
        {
            fs.Read(buffer, 0, buffer.Length);
        }

        return buffer;
    }

    void InitSocketEnv()
    {
        try
        {
            //string RemoteIp = "192.168.3.188";
            //string RemoteIp = "192.168.3.197";
            //string ImageRemotePort = netConfig.GetString("RemotePort");
            string ImageRemotePort = "4567";

            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            endPoint = new IPEndPoint(IPAddress.Parse(RemoteIp), int.Parse(ImageRemotePort));
            socket.Connect(endPoint);
            print("Socket连接成功.目标为:" + endPoint);
        }
        catch (Exception)
        {
            print("Socket连接失败");
            throw;
        }
    }



    //IEnumerator SetSkt(byte[] byte1)
    //{
    //    InitSocketEnv();
    //    yield return new WaitForSeconds(2);
    //    SendPhotoMessage(byte1);
    //}
    private void OnDisable()
    {
        socket.Close();
    }   
}

接收:

using UnityEngine;
using System.Collections;
using System.Net;
using System.Net.Sockets;
using System.IO;
using System.Threading;
using System.Collections.Generic;
using System;
using Newtonsoft.Json;

public class RecivePhoto : MonoBehaviour
{
    public static RecivePhoto Instance;
    private Socket m_socket = null;
    private IPEndPoint m_ipEp = null;

    private Thread m_thread = null;
    private bool isRunningThread = false;

    public Queue<byte[]> m_queue;

    public string ImgeSavePath;

    private List<Socket> list;

    public XMLConfig mLConfig;

    public bool UseingData;

    //保存图像信息,时间戳+像素RGB
    private struct ImageData
    {
        public long timestamp;
        public byte[] data;
    }
    private void Awake()
    {
        Instance = this;
    }
    // Use this for initialization
    void Start()
    {
        ImgeSavePath = Application.streamingAssetsPath + "/AutoInfo/Textures/";
        m_queue = new Queue<byte[]>();
        InitSocketEnv();

        list = new List<Socket>();
    }

    string Msg = "";

    // Update is called once per frame
    void Update()
    {
        if (m_queue.Count > 0 && UseingData == false)
        {
            //print("m_queue.Count:" + m_queue.Count);

            //使用数据 //移至Loading之后
            //byte[] temp = m_queue.Dequeue();
            //string strbaser64 = Convert.ToBase64String(temp);
            //string str = System.Text.Encoding.UTF8.GetString(temp);
            //print(str);

            //JsonManager.Instance.JsonToData(str);
            //JsonManager.Instance.DataToJson();

            //AutoManager.Instance.UseAutoData();

            //显示LoadingUI
            ShowPageScript.Instance.LoadingUI.gameObject.SetActive(true);



            //不隐藏
            //MoNiDaPing.Instance.QrImage.gameObject.SetActive(false);
            UseingData = true;
            System.GC.Collect();
        }
    }

    void ReciveMeg(Socket socketClinet)
    {
        while (isRunningThread)
        {
            Debug.Log("information");
            string sendStr = "server information";
            byte[] bs = System.Text.Encoding.UTF8.GetBytes(sendStr);

            //判断是否断开
            //if (socketClinet.Poll(500, SelectMode.SelectRead))
            //{
            //    socketClinet.Close();
            //    list.Remove(socketClinet);
            //    break;
            //}

            try
            {
                //Socket.Select(list,null,null,500);

                socketClinet.Send(bs, bs.Length, 0);

                byte[] newbuffer = new byte[40000000];
                int length = socketClinet.Receive(newbuffer, newbuffer.Length, SocketFlags.None);

                int i = 0;
                while( length < 40000000)
                {
                    if(socketClinet.Available == 0)
                    {
                        break;
                    }

                    byte[] tempbuffer = new byte[40000000];
                    int  templength = socketClinet.Receive(tempbuffer, tempbuffer.Length, SocketFlags.None);

                    Debug.Log(templength);

                    for (int j = length ; j < length + templength; j++)
                    {
                        newbuffer[j] = tempbuffer[j - length];
                    }

                    length = length + templength;

                    i = i + 1;

                    if(i >10)
                    {
                        break;
                    }
                }

                byte[] outByte = new byte[length];
                Array.Copy(newbuffer, 0, outByte, 0, length);

                string strbaser64 = System.Text.Encoding.UTF8.GetString(outByte);

                print("添加 +    " + length +"     ++ " + strbaser64);

                //如果服务器断开则移除队列中的无效元素
                if (length != 0)
                {
                    //Francis
                    m_queue.Enqueue(newbuffer);
                    //print(m_queue.Count);
                }
            }
            catch (Exception ex)
            {
                socketClinet.Close();
                list.Remove(socketClinet);

                Debug.Log("接收 Exception");
                
                break;
            }
        }
        Debug.Log("stop");
        UseingData = false;
    }

    void ReciveScoket()
    {
        while (isRunningThread)
        {
            Socket sk = m_socket.Accept();
            sk.ReceiveBufferSize = 40000000;
            list.Add(sk);

            Thread t = new Thread(new ThreadStart(() => ReciveMeg(list[list.Count - 1])));
            t.IsBackground = true;
            t.Start();

            Debug.Log("accept");
        }
    }

    void InitSocketEnv()
    {
        m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
        string LocalIp = GeIP.IP(GeIP.address.IPv4);
        m_ipEp = new IPEndPoint(IPAddress.Parse(LocalIp), 4567);
        //m_ipEp = new IPEndPoint(IPAddress.Parse("192.168.3.103"), 4567);
        m_socket.Bind(m_ipEp);
        m_socket.Listen(7);
        m_socket.ReceiveBufferSize = 40000000;

        isRunningThread = true;
        m_thread = new Thread(ReciveScoket);
        m_thread.IsBackground = true;
        m_thread.Start();
        print("thread Start");

        print(m_ipEp);
    }

    void OnDistory()
    {
        isRunningThread = false;
        m_socket.Close();
        for (int i = 0; i < list.Count; i++)
        {
            list[i].Close();
        }
    }
}

解决了连续发送接收会丢包的问题

posted @ 2022-06-22 18:05  哒哒哒~~~  阅读(101)  评论(0编辑  收藏  举报