C# Client 0.0.0.7
C# Library to interface with Corelink
Loading...
Searching...
No Matches
CorelinkUDP.cs
Go to the documentation of this file.
1using System;
2using System.Collections.Generic;
3using System.Net;
4using System.Net.Sockets;
5using System.Text;
6using System.Threading;
7using UnityEngine;
8
9namespace CoreLink
10{
14 public class CorelinkUDP
15 {
16 private UdpClient udpClient;
17 private int udpPort;
18 private Thread udpThread;
19 private bool active;
20 private string ControlIP;
21 private List<uint> allowedStreams;
22 private List<ReceiverStreamParams> receiverStreams;
31 public CorelinkUDP(string ControlIP, int udpPort,
32 ref List<uint> allowedStreams, ref List<ReceiverStreamParams> receiverStreams)
33 {
34 this.allowedStreams = allowedStreams;
35 this.receiverStreams = receiverStreams;
36 this.active = true;
37 this.ControlIP = ControlIP;
38 this.udpPort = udpPort;
39 udpClient = new UdpClient(ControlIP, udpPort);
41 }
42
43
47 #region [Receiver]
48
53 {
54 udpThread = new Thread(listenForUDPData);
55 udpThread.Start();
56 }
57
63 void listenForUDPData()
64 {
65 IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ControlIP), udpPort);
66 Debug.Log("Opening UDP Connection" + ep);
67
68 UdpState state = new UdpState(ep, udpClient);
69
70 udpClient.BeginReceive(new AsyncCallback(UDPReceiveCallback), state);
71 // idle time to check if the application quits
72 while (active)
73 {
74 Thread.Sleep(100);
75 }
76
77 Debug.Log("Closing UDP Connection");
78 udpClient.Close();
79 }
85 void UDPReceiveCallback(IAsyncResult ar)
86 {
87 if (!active)
88 {
89 return;
90 }
91 UdpClient c = ((UdpState)(ar.AsyncState)).c;
92 IPEndPoint e = ((UdpState)(ar.AsyncState)).e;
93 byte[] buf = udpClient.EndReceive(ar, ref e);
94
95 parseUDPMessage(buf);
96 UdpState state = new UdpState(e, c);
97 udpClient.BeginReceive(new AsyncCallback(UDPReceiveCallback), state);
98 }
99
106 void parseUDPMessage(byte[] udpBuf)
107 {
108 int headerSize = BitConverter.ToUInt16(udpBuf, 0);
109 int dataSize = (int)BitConverter.ToUInt16(udpBuf, 2);
110 uint streamID = (uint)BitConverter.ToUInt16(udpBuf, 4);
111 int federationID = (int)BitConverter.ToUInt16(udpBuf, 6); // Unused for now
112 if (dataSize == 0)
113 return;
114
115 byte[] header = new byte[headerSize];
116 if (headerSize != 0)
117 {
118 Buffer.BlockCopy(udpBuf, 8, header, 0, headerSize);
119 }
120 byte[] msg = new byte[dataSize];
121 Buffer.BlockCopy(udpBuf, 8 + headerSize, msg, 0, dataSize);
122 // SimpleJSON.JSONNode root = SimpleJSON.JSON.Parse(Encoding.ASCII.GetString(header));
123
124 if (allowedStreams.Contains(streamID))
125 {
126 for (int i = 0; i < receiverStreams.Count; i++)
127 {
128 if (receiverStreams[i].streamIDs.Contains(streamID))
129 {
130 receiverStreams[i].ReceiverStream.OnMessage(streamID, header, msg);
131 }
132 }
133 }
134 }
135
141 public void receiverPing(uint streamID)
142 {
143 int num = 0;
144 byte[] numByte = BitConverter.GetBytes(num);
145 byte[] UDPInitMsg = constructUDPMsg(streamID, new byte[0], numByte);
146 udpClient.Send(UDPInitMsg, UDPInitMsg.Length);
147
148 Debug.Log("Sent empty receiver packet");
149 }
150 #endregion
151
155 #region [Sender]
162 public void send(uint streamID, byte[] header, byte[] data)
163 {
164 if (udpClient == null) throw new Exception("udpClient undefined");
165
166 try
167 {
168 byte[] UDPInitMsg = constructUDPMsg(streamID, header, data);
169 udpClient.Send(UDPInitMsg, UDPInitMsg.Length);
170 }
171 catch (SocketException socketException)
172 {
173 Debug.LogException(socketException);
174 throw new Exception("Socket exception: " + socketException);
175 }
176 }
177
185 byte[] constructUDPMsg(uint streamID, byte[] header, byte[] data)
186 {
187 byte[] dataPacket = new byte[8 + header.Length + data.Length];
188
189 byte[] headerLengthBytes = BitConverter.GetBytes((ushort)header.Length);
190 // TODO: Check to make sure this will return 2 bytes if size is 0
191 dataPacket[0] = headerLengthBytes[0];
192 dataPacket[1] = headerLengthBytes[1];
193
194 byte[] dataLengthBytes = BitConverter.GetBytes((ushort)data.Length);
195 dataPacket[2] = dataLengthBytes[0];
196 dataPacket[3] = dataLengthBytes[1];
197
198 // TODO: Not entirely sure why we cast to ushort
199 byte[] streamIDBytes = BitConverter.GetBytes((ushort)streamID);
200 dataPacket[4] = streamIDBytes[0];
201 dataPacket[5] = streamIDBytes[1];
202
203 // TODO: Hardcoding federation ID 0 for now
204 dataPacket[6] = 0;
205 dataPacket[7] = 0;
206
207 if (header.Length > 0)
208 {
209 string headerStr = JsonUtility.ToJson(header);
210 byte[] headerByte = Encoding.ASCII.GetBytes(headerStr);
211 Buffer.BlockCopy(headerByte, 0, dataPacket, 8, headerByte.Length);
212 }
213
214 Buffer.BlockCopy(data, 0, dataPacket, 8 + header.Length, data.Length);
215
216 return dataPacket;
217 }
218
219 #endregion
223 public void stopConnection()
224 {
225 active = false;
226 }
227 }
228}