목차

     

     

    목차

      Unity3D 프로세스와 윈도우 폼 간의 통신 수행시 Tcp 서버에서 여러 클라이언트(유니티 프로세스)를 받을 수 있도록 하는 소스.
       

      Packet.cs

      using System;
       
      namespace Unity.Network
      {
          public enum PacketType
          {
              None, Connect, Reconnect, Disconnect, Chat,
          }
       
          [Serializable]
          public class Packet
          {
              public PacketType Type;
          }
       
          [Serializable]
          public class Connect : Packet
          {
              public string UserName;
          }
       
          [Serializable]
          public class ChatMessage : Packet
          {
              public string Message;
          }
      }

      PacketBinder.cs

      using System;

      using System.Reflection;

      using System.Runtime.Serialization;

       

      namespace Unity.Network

      {

          sealed class PacketBinder : SerializationBinder

          {

              public override Type BindToType(string assemblyName, string typeName)

              {

                  Type returntype = null;

                  assemblyName = Assembly.GetExecutingAssembly().FullName;

       

                  string sharedAssemblyName = "SharedAssembly, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null";

                  typeName = typeName.Replace(sharedAssemblyName, assemblyName);

       

                  returntype = Type.GetType(String.Format("{0}, {1}", typeName, assemblyName));

                  return returntype;

              }

          }

      }

       

      LocalClient.cs

      using System;

      using System.IO;

      using System.Net.Sockets;

      using System.Runtime.Serialization.Formatters.Binary;

       

      namespace Unity.Network

      {

          public class LocalClient

          {

              private const string LocalIp = "127.0.0.1";

              public const int PortNumber = 10001;

              private const int BufferSize = 2048;

       

              private NetworkStream _stream;

              public NetworkStream Stream

              {

                  get { return _stream; }

              }

       

              private readonly BinaryFormatter _formatter;

       

              private TcpClient _client;

              private byte[] _buffer;

       

              public string UserName { get; set; }

       

              public event Connected OnConnected;

              public event Disconnected OnDisconnected;

              public event ConnectError OnConnectError;

              public event ReceiveObject OnReceiveObject;

       

              /// <summary>

              /// 클라이언트용 생성자

              /// </summary>

              public LocalClient() : this(null)

              {

                  

              }

       

              /// <summary>

              /// 서버용 생성자

              /// </summary>

              /// <param name="client">이미 생성된 TcpClient</param>

              public LocalClient(TcpClient client)

              {

                  _client = client;

       

                  _formatter = new BinaryFormatter();

                  _formatter.Binder = new PacketBinder();

       

                  _buffer = new byte[BufferSize];

              }

       

              public void Start()

              {

                  if (_client != null)

                  {

                      _stream = _client.GetStream();

       

                      //서버 -> 클라이언트

                      BeginRead();

                  }

                  else

                  {

                      //클라이언트 -> 서버

                      StartClient();

                  }

              }

       

              private void StartClient()

              {

                  //클라이언트 -> 서버

                  _client = new TcpClient();

       

                  try

                  {

                      _client.BeginConnect(LocalIp, PortNumber, EndConnect, null);

                  }

                  catch (SocketException ex)

                  {

                      if (OnConnectError != null)

                          OnConnectError(ex);

                  }

              }

       

              private void EndConnect(IAsyncResult result)

              {

                  try

                  {

                      _client.EndConnect(result);

                      _stream = _client.GetStream();

       

                      if (OnConnected != null)

                          OnConnected(this);

       

       

                      BeginRead();

                  }

                  catch (SocketException ex)

                  {

                      if (OnConnectError != null)

                          OnConnectError(ex);

                  }

              }

       

              private void BeginRead()

              {

                  _stream.BeginRead(_buffer, 0, BufferSize, new AsyncCallback(ReadObject), null);

              }

       

              public void Close()

              {

                  _stream.Close();

                  _client.Close();

              }

       

              private void ReadObject(IAsyncResult result)

              {

                  int readSize = 0;

       

                  try

                  {

                      lock (_stream)

                      {

                          readSize = _stream.EndRead(result);

                      }

       

                      if (readSize < 1)

                          throw new Exception("Disconnect");

       

       

                      Packet packet = new Packet();

                      using (MemoryStream stream = new MemoryStream(_buffer))

                      {

                          packet = (Packet)_formatter.Deserialize(stream);

                      }

       

                      if (OnReceiveObject != null)

                          OnReceiveObject(this, packet);

       

       

                      lock (_stream)

                      {

                          BeginRead();

                      }

                  }

                  catch(Exception ex)

                  {

                      if (OnDisconnected != null)

                          OnDisconnected(this, ex);

                  }

              }

       

              public void SendPacket(Packet packet)

              {

                  byte[] data = null;

                  try

                  {

                      using (MemoryStream stream = new MemoryStream())

                      {

                          _formatter.Serialize(stream, packet);

       

                          data = stream.ToArray();

                      }

       

                      if (data == null || data.Length < 1)

                          return;

       

                      _stream.Write(data, 0, data.Length);

                      _stream.Flush();

                  }

                  catch

                  {

                      

                  }//try

              }

          }

       

          public delegate void Connected(LocalClient client);

          public delegate void Disconnected(LocalClient client, Exception ex);

          public delegate void ConnectError(SocketException ex);

          public delegate void ReceiveObject(LocalClient client, Packet packet);

      }

       

      NetMultiServer.cs

      using System;

      using System.Collections.Generic;

      using System.Net.Sockets;

      using System.Threading;

      using Unity.Network;

       

      namespace CsConnector

      {

          public class NetMultiServer

          {        

              private readonly TcpListener _listener;

       

              private readonly Dictionary<string, LocalClient> _clientTable;

              private readonly Thread _listenerThread;

       

              public NetMultiServer()

              {

                  _clientTable = new Dictionary<string, LocalClient>();

       

                  _listener = new TcpListener(System.Net.IPAddress.Any, LocalClient.PortNumber);

                  _listenerThread = new Thread(new ThreadStart(DoListen));

              }

       

              public void Start()

              {

                  _listenerThread.Start();

              }

       

              public void Close()

              {

                  _listener.Stop();

              }

       

              private void DoListen()

              {

                  try

                  {

                      _listener.Start();

       

                      do

                      {

                          TcpClient tcpClient = _listener.AcceptTcpClient();

       

                          LocalClient localClient = new LocalClient(tcpClient);

                          localClient.OnReceiveObject += ReceiveObject;

                          localClient.Start();

                      }

                      while (true);

                  }

                  catch (Exception)

                  {

       

                  }//try

              }

       

              private void ReceiveObject(LocalClient client, Packet packet)

              {

                  if (packet == null)

                      return;

       

                  switch (packet.Type)

                  {

                      case PacketType.Connect: OnConnected(client, packet); break;

                  }

              }

       

              private void OnConnected(LocalClient client, Packet packet)

              {

                  Connect connect = packet as Connect;

                  if (connect == null)

                      return;

       

       

                  client.UserName = connect.UserName;

                  _clientTable.Add(client.UserName, client);

              }

       

              private void SendPacket(LocalClient client, Packet packet)

              {

                  client.SendPacket(packet);

              }

          }

      }

       

      NetClient.cs

      using System;

      using Unity.Network;

      using UnityEngine;

       

      public class NetClient

      {

          private const string UserName = "UnityClient";

       

          private LocalClient _client;

       

          public event Chat OnChat;

       

          public NetClient()

          {

              

          }

       

          public void Start()

          {

              _client = new LocalClient();

              _client.OnConnected += Connected;

              _client.Start();

          }

       

          public void Close()

          {

              _client.Close();

          }

       

          private void Connected(LocalClient client)

          {

              Connect connect = new Connect()

              {

                  Type = PacketType.Connect,

                  UserName = UserName,

              };

       

              _client.UserName = UserName;

              _client.SendPacket(connect);

          }

       

          private void ConnectError(Exception ex)

          {

              Debug.Log("접속 에러\n" + ex.ToString());

          }

       

          private void ReceiveObject(LocalClient client, Packet packet)

          {

              if (packet == null)

                  return;

       

              switch (packet.Type)

              {

                  case PacketType.Chat: OnChatMessage(client, packet); break;

              }

          }

       

          private void OnChatMessage(LocalClient client, Packet packet)

          {

              ChatMessage message = packet as ChatMessage;

              if (message == null)

                  return;

       

              if (OnChat != null)

                  OnChat(message.Message);

          }

       

          private void SendPacket(LocalClient client, Packet packet)

          {

              client.SendPacket(packet);

          }

       

          public delegate void Chat(string message);

      }

       

       

      목차

        CoroutineRunner.cs

        using System.Collections;

        using System.Collections.Generic;

        using UnityEditor;

         

        public static class CoroutineRunner

        {

            private static List _coroutineList = null;

            private static List _bufferList = null;

         

            public static IEnumerator Start(IEnumerator iterator)

            {

                if (_coroutineList == null)

                    _coroutineList = new List();

                

                if (_bufferList == null)

                    _bufferList = new List();

                

                if (_coroutineList.Count == 0)

                    EditorApplication.update += Update;

                

                _bufferList.Add(iterator);

         

                return iterator;

            }

         

            private static bool Find(IEnumerator iterator)

            {

                foreach (EditorCoroutine coroutine in _coroutineList)

                {

                    if (coroutine.Find(iterator) == true)

                        return true;

                }

         

                return false;

            }

         

            private static void Update()

            {

                _coroutineList.RemoveAll

                (

                    coroutine => { return coroutine.MoveNext() == false; }

                );

         

                if (_bufferList.Count > 0)

                {

                    foreach (IEnumerator iterator in _bufferList)

                    {

                        if (Find(iterator) == false)

                            _coroutineList.Add(new EditorCoroutine(iterator));

                    }

         

                    _bufferList.Clear();

                }

         

                if (_coroutineList.Count == 0)

                {

                    EditorApplication.update -= Update;

                }

            }

         

            private class EditorCoroutine : IEnumerator

            {

                private Stack _stack;

         

                public EditorCoroutine(IEnumerator iterator)

                {

                    _stack = new Stack();

                    _stack.Push(iterator);

                }

         

                public bool MoveNext()

                {

                    IEnumerator i = _stack.Peek();

         

                    if (i.MoveNext() == true)

                    {

                        object result = i.Current;

                        if (result != null && result is IEnumerator)

                        {

                            _stack.Push((IEnumerator)result);

                        }

         

                        return true;

                    }

                    else

                    {

                        if (_stack.Count > 1)

                        {

                            _stack.Pop();

         

                            return true;

                        }

                    }

         

                    return false;

                }

         

                public void Reset()

                {

                    throw new System.NotSupportedException(

                              "This Operation Is Not Supported.");

                }

         

                public object Current

                {

                    get { return _stack.Peek().Current; }

                }

         

                public bool Find(IEnumerator iterator)

                {

                    return _stack.Contains(iterator);

                }

            }

        }