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();
}
}
}
解决了连续发送接收会丢包的问题