728x90
반응형
1. 내용
(1) 권장 포트 번호 : 49152 ~ 65535
포트 번호 |
내용 |
0 |
사용하지 않음. |
1 ~1023 |
잘 알려진 포트(Well-known port) |
1024 ~ 49151 |
등록된 포트(Registered port) |
49152 ~ 65535 |
동적 포트(Dynamic port) |
(2) 전송 패키지 사이즈
Udp는 이론상으로는 65507 byte까지 보낼수 있지만, 내부 통신이 아닌 경우 1024 byte이내를 권장합니다.
(3) 소스 내용
- 유니티와 유니티, 또는 C#과의 통신, 또는 C++와의 통신
- 클래스 : UdpClient
- 개체 직렬화 : Marshal
- 전송 패킷 : 구조체 ↔ 바이트 배열
2. 소스
2.1 Receiver.cs
using UnityEngine;
using System;
using System.Net;
using System.Threading;
using System.Runtime.InteropServices;
using System.Net.Sockets;
public class Receiver : MonoBehaviour
{
private UdpClient m_Receiver;
public int m_Port = 50001;
public Packet m_ReceivePacket = new Packet();
private byte[] m_ReceiveBytes;
private IPEndPoint m_IpEndPoint;
private bool m_IsThreading;
private Thread m_ThrdReceive;
void Start()
{
InitReceiver();
}
void OnApplicationQuit()
{
CloseReceiver();
}
void InitReceiver()
{
m_IpEndPoint = new IPEndPoint(IPAddress.Any, m_Port);
m_Receiver = new UdpClient(m_IpEndPoint);
m_ThrdReceive = new Thread(ReceivePacket);
m_IsThreading = true;
if (m_ThrdReceive.ThreadState != ThreadState.Running)
{
m_ThrdReceive.Start();
}
}
void ReceivePacket()
{
while (m_IsThreading)
{
try
{
m_ReceiveBytes = m_Receiver.Receive(ref m_IpEndPoint);
DoReceive();
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
}
}
void DoReceive()
{
m_ReceivePacket = ByteArrayToStruct<Packet>(m_ReceiveBytes);
// 받은 값 처리 ...
Debug.LogFormat($"BoolVariable = {m_ReceivePacket.m_BoolVariable} " +
$"IntlVariable = {m_ReceivePacket.m_IntVariable} " +
$"m_IntArray[0] = {m_ReceivePacket.m_IntArray[0]} " +
$"m_IntArray[1] = {m_ReceivePacket.m_IntArray[1] } " +
$"FloatlVariable = {m_ReceivePacket.m_FloatlVariable} " +
$"StringlVariable = {m_ReceivePacket.m_StringlVariable}");
//출력: BoolVariable = True IntlVariable = 2941 m_IntArray[0] = 0 m_IntArray[1] = 1 FloatlVariable = 34.06423 StringlVariable = CoderZero 코더제로
}
void CloseReceiver()
{
m_IsThreading = false;
if (m_Receiver != null)
m_Receiver.Close();
if (m_ThrdReceive != null)
{
try
{
m_ThrdReceive.Abort();
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
}
}
T ByteArrayToStruct<T>(byte[] arr)
{
object value = null;
int size = Marshal.SizeOf(typeof(T));
IntPtr ptr = Marshal.AllocHGlobal(size);
try
{
Marshal.Copy(arr, 0, ptr, size);
value = Marshal.PtrToStructure(ptr, typeof(T));
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
finally
{
Marshal.FreeHGlobal(ptr);
}
return (T)value;
}
}
2.2 Sender.cs
using UnityEngine;
using System.Net.Sockets;
using System.Net;
using System;
using System.Threading;
using System.Runtime.InteropServices;
public class Sender : MonoBehaviour
{
private UdpClient m_Sender;
public string m_Ip = "127.0.0.1";
public int m_Port = 50001;
public Packet m_SendPacket = new Packet();
private IPEndPoint m_IpEndPoint;
private byte[] m_SendBytes;
private bool m_IsThreading;
private Thread m_ThrdSend;
void Start()
{
InitSender(m_Ip, m_Port);
}
void Update()
{
SetSendPacket();
}
void OnApplicationQuit()
{
CloseSender();
}
void InitSender(string ip, int port)
{
m_IpEndPoint = new IPEndPoint(IPAddress.Parse(ip), port);
m_Sender = new UdpClient();
m_Sender.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
m_Sender.Connect(m_IpEndPoint);
m_ThrdSend = new Thread(ThrdSendPacket);
m_IsThreading = true;
if (m_ThrdSend.ThreadState != System.Threading.ThreadState.Running)
{
m_ThrdSend.Start();
}
}
void ThrdSendPacket()
{
while (m_IsThreading)
{
Thread.Sleep(16);
try
{
m_Sender.Send(m_SendBytes, m_SendBytes.Length);
}
catch (Exception e)
{
// Debug.Log(e.ToString());
}
}
}
void CloseSender()
{
m_IsThreading = false;
if (m_Sender != null)
m_Sender.Close();
if (m_ThrdSend != null)
{
try
{
m_ThrdSend.Abort();
}
catch (Exception e)
{
Debug.Log(e.ToString());
}
}
}
void SetSendPacket()
{
m_SendPacket.m_BoolVariable = !m_SendPacket.m_BoolVariable;
m_SendPacket.m_IntVariable++;
if (m_SendPacket.m_IntVariable >= int.MaxValue - 1)
m_SendPacket.m_IntVariable = default(int);
m_SendPacket.m_IntArray = new int[2];
m_SendPacket.m_IntArray[0] = 0;
m_SendPacket.m_IntArray[1] = 1;
m_SendPacket.m_FloatlVariable = UnityEngine.Random.Range(0f, 100.0f);
m_SendPacket.m_StringlVariable = "CoderZero 코더제로";
m_SendBytes = StructToByteArray(m_SendPacket);
}
byte[] StructToByteArray(object obj)
{
int datasize = Marshal.SizeOf(obj);
IntPtr buff = Marshal.AllocHGlobal(datasize);
Marshal.StructureToPtr(obj, buff, false);
byte[] data = new byte[datasize];
Marshal.Copy(buff, data, 0, datasize);
Marshal.FreeHGlobal(buff);
return data;
}
}
2.3 Packets.cs
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi, Pack = 1)]
[Serializable]
public struct Packet
{
[MarshalAs(UnmanagedType.Bool)]
public bool m_BoolVariable;
public int m_IntVariable;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2)]
public int[] m_IntArray;
public float m_FloatlVariable;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]
public string m_StringlVariable;
}
728x90
반응형
'프로그램 > 유니티 네트워크' 카테고리의 다른 글
[유니티 네트워크] UdpServer, UdpClient 구조체 전송 (UdpClient) (2) | 2020.07.30 |
---|---|
[유니티 네트워크] UdpServer, UdpClient 구조체 전송 (Socket) (1) | 2020.07.28 |
[유니티 네트워크] 비동기 UdpSender, UdpReceiver 구조체 전송 (UdpClient) (0) | 2020.05.06 |
[유니티 네트워크] 비동기 UdpSender, UdpReceiver 문자열 전송 (UdpClient) (0) | 2020.05.05 |
[유니티 네트워크] 비동기 UdpSender, UdpReceiver 클래스 전송 (UdpClient) (0) | 2020.05.05 |