我有一个简单的工作服务器,它从数据收集设备发送二进制文件,套接字连接正常工作,我的Unity客户端和其他客户端(如matlab客户端)都可以正确接收数据。
然后Unity中的客户端尝试从该服务器接收数据并将每个数据包的字节分段为3D坐标数组。
每个帧应该是512x424像素大,这就是为什么我需要等到数据填充512x424字节并进行分割
Unity在套接字连接和接收阶段运行正常,它将在处理阶段卡住(停顿):@echo off
setlocal EnableDelayedExpansion
rem Load the number of occurrences of each letter from "LetterPerSample.txt" file
rem and create the desired files
set "letters=abcdefghijklmnopqrstuvwxyz"
set "i=0"
for /F %%b in (LetterPerSample.txt) do (
for %%i in (!i!) do set "letter=!letters:~%%i,1!"
set /A i+=1
set "num=%%b"
for /L %%g in (1,1,!num!) do (
set "index=%%g"
echo !letter!>letter_labels\!letter!\!letter!_!index!.lab
)
)
我已阅读此SO帖子: Getting UdpClient Receive data back in the Main thread 并相应地更改了我的代码,但问题仍然存在。
我做错了吗?感谢您的帮助:))
ProcessFrame((byte[])state.buffer.Clone())
代码---数据处理
public class SomeClass: MonoBehaviour { public GameObject sphere; const int IMGW = 512; const int IMGH = 424; const int MAXBODY = 6; const int NUMJOINT = 25; const int READ_BUFFER_SIZE = (4 * 3 + 4 * 1 + 4 * 1) * (IMGW * IMGH + MAXBODY * NUMJOINT); const int PORT_NUM = 20156; public string response = String.Empty; private Queue queue; private System.Object queueLock; private int bytesRead; // ManualResetEvent instances signal completion. private static ManualResetEvent connectDone = new ManualResetEvent(false); private static ManualResetEvent sendDone = new ManualResetEvent(false); private static ManualResetEvent receiveDone = new ManualResetEvent(false); // State object for receiving data from remote device. public class StateObject { // Client socket. public Socket workSocket = null; // Receive buffer. public const int BufferSize = (4 * 3 + 4 * 1 + 4 * 1) * (IMGW * IMGH + MAXBODY * NUMJOINT); public byte[] buffer = new byte[BufferSize]; } // We use this to keep tasks needed to run in the main thread private static readonly Queue<Action> tasks = new Queue<Action>(); // Use this for initialization void Start () { queueLock = new object(); queue = new Queue(); this.StartClient(); // Test object sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.position = new Vector3(0, -1, 10); } // Update is called once per frame void Update () { this.HandleTasks(); } void HandleTasks() { while (tasks.Count > 0) { Action task = null; lock (tasks) { if (tasks.Count > 0) { task = tasks.Dequeue(); } } task(); } } public void QueueOnMainThread(Action task) { lock (tasks) { tasks.Enqueue(task); } } private void StartClient() { try { IPAddress ipAddress = IPAddress.Parse("127.0.0.1"); IPEndPoint remoteEP = new IPEndPoint(ipAddress, PORT_NUM); Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // Connect to the remote endpoint. client.BeginConnect(remoteEP, new AsyncCallback(ConnectCallback), client); connectDone.WaitOne(); Receive(client); receiveDone.WaitOne(); Console.WriteLine("Response received : {0}", response); // Release the socket client.Shutdown(SocketShutdown.Both); client.Close(); } catch (Exception e) { Debug.Log(e.ToString()); } } private void ConnectCallback(IAsyncResult ar) { try { // Retrieve the socket from the state object. Socket client = (Socket)ar.AsyncState; // Complete the connection. client.EndConnect(ar); // Signal that the connection has been made. connectDone.Set(); } catch (Exception e) { String error = e.ToString(); Console.WriteLine(e.ToString()); fnDisconnect(); } } private void Receive(Socket client) { try { // Create the state object. StateObject state = new StateObject(); state.workSocket = client; bytesRead = 0; // Begin receiving the data from the remote device. client.BeginReceive(state.buffer, bytesRead, StateObject.BufferSize, 0, new AsyncCallback(ReceiveCallback), state); } catch (Exception e) { Console.WriteLine(e.ToString()); } } private void ReceiveCallback(IAsyncResult ar) { try { // Retrieve the state object and the client socket // from the asynchronous state object. StateObject state = (StateObject)ar.AsyncState; Socket client = state.workSocket; // Read data from the remote device. int numOfBytesRead = client.EndReceive(ar); if (numOfBytesRead > 0) { bytesRead += numOfBytesRead; if (bytesRead == StateObject.BufferSize) { this.QueueOnMainThread(() => { // All the data has arrived; put it in response. ProcessFrame((byte[])state.buffer.Clone()); }); Receive(client); } else { // Get the rest of the data. client.BeginReceive(state.buffer, bytesRead, StateObject.BufferSize - bytesRead, 0, new AsyncCallback(ReceiveCallback), state); } } else { receiveDone.Set(); } } catch (Exception e) { Console.WriteLine(e.ToString()); } }
感谢@Programmer的建议,我按照他提供的工作套接字客户端链接。
答案 0 :(得分:1)
整个代码一团糟。您应该使用Async
而不是byte[] bufferCopy = (byte[])buffer.Clone();
来完成更少的代码。
任何方式,用
替换byte[] bufferCopy = new byte[buffer.Length];
System.Buffer.BlockCopy(buffer, 0, bufferCopy, 0, bufferCopy.Length);
代码行
ProcessFrame((byte[])state.buffer.Clone());
对于ProcessFrame(state.buffer);
,只需传入数据而不进行克隆。所以应该替换为
PATCH /users/:id => user#update
这应该可以解决问题,假设这是代码中唯一的问题。
编辑:
Here Unity的完整TCP服务器代码。将代码移植到UDP,这应该适合您。