Просмотр исходного кода

ENetCS增加断开异常处理,避免在connect accept receive一直挂住

tanghai 13 лет назад
Родитель
Сommit
1087ea7d75

+ 1 - 1
CSharp/App/Modules/Robot/Packages.config

@@ -4,5 +4,5 @@
   <package id="CommonServiceLocator" version="1.0" targetFramework="net45" />
   <package id="Prism" version="4.1.0.0" targetFramework="net45" />
   <package id="Prism.MEFExtensions" version="4.1.0.0" targetFramework="net45" />
-  <package id="protobuf-net" version="2.0.0.480" targetFramework="net45" />
+  <package id="protobuf-net" version="2.0.0.612" targetFramework="net45" />
 </packages>

+ 3 - 2
CSharp/App/Modules/Robot/Robot.csproj

@@ -40,8 +40,9 @@
     </Reference>
     <Reference Include="PresentationCore" />
     <Reference Include="PresentationFramework" />
-    <Reference Include="protobuf-net">
-      <HintPath>..\..\..\packages\protobuf-net.2.0.0.480\lib\net40\protobuf-net.dll</HintPath>
+    <Reference Include="protobuf-net, Version=2.0.0.612, Culture=neutral, PublicKeyToken=257b51d87d2e4d67, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\packages\protobuf-net.2.0.0.612\lib\net40\protobuf-net.dll</HintPath>
     </Reference>
     <Reference Include="System" />
     <Reference Include="System.ComponentModel.Composition" />

+ 6 - 6
CSharp/App/Modules/Robot/RobotViewModel.cs

@@ -15,7 +15,7 @@ namespace Modules.Robot
 	[Export(contractType: typeof (RobotViewModel)), PartCreationPolicy(creationPolicy: CreationPolicy.NonShared)]
 	internal class RobotViewModel: NotificationObject, IDisposable
 	{
-		private readonly Host host;
+		private readonly ClientHost clientHost;
 		private string logText = "";
 
 		private readonly DispatcherTimer timer = new DispatcherTimer(DispatcherPriority.Normal)
@@ -41,9 +41,9 @@ namespace Modules.Robot
 		public RobotViewModel()
 		{
 			Library.Initialize();
-			this.host = new Host();
+			this.clientHost = new ClientHost();
 
-			this.timer.Tick += delegate { this.host.Run(); };
+			this.timer.Tick += delegate { this.clientHost.RunOnce(); };
 			this.timer.Start();
 		}
 
@@ -60,15 +60,15 @@ namespace Modules.Robot
 
 		protected virtual void Disposing(bool disposing)
 		{	
-			this.host.Dispose();
+			this.clientHost.Dispose();
 		}
 
 		public async void StartClient()
 		{
 			try
 			{
-				var address = new Address { HostName = "192.168.10.246", Port = 8901 };
-				using (Peer peer = await this.host.ConnectAsync(address))
+				var address = new Address { HostName = "192.168.10.246", Port = 8900 };
+				using (Peer peer = await this.clientHost.ConnectAsync(address))
 				{
 					using (Packet packet = await peer.ReceiveAsync())
 					{

+ 2 - 2
CSharp/Platform/ENetCS/Address.cs

@@ -41,8 +41,8 @@ namespace ENet
 			}
 			set
 			{
-				var nameToIpAddress = Dns.GetHostEntry(value);
-				foreach (IPAddress address in nameToIpAddress.AddressList)
+				IPAddress[] addresslist = Dns.GetHostAddresses(value);
+				foreach (IPAddress address in addresslist)
 				{
 					this.ip = BitConverter.ToUInt32(address.GetAddressBytes(), 0);
 					return;

+ 121 - 0
CSharp/Platform/ENetCS/ClientHost.cs

@@ -0,0 +1,121 @@
+using System;
+using System.Threading.Tasks;
+using Log;
+
+namespace ENet
+{
+	public sealed class ClientHost : Host
+	{
+		public ClientHost(uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID,
+				uint channelLimit = 0, uint incomingBandwidth = 0,
+				uint outgoingBandwidth = 0, bool enableCrc = true)
+		{
+			if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
+			{
+				throw new ArgumentOutOfRangeException("peerLimit");
+			}
+			CheckChannelLimit(channelLimit);
+
+			this.host = NativeMethods.enet_host_create(IntPtr.Zero, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth);
+
+			if (this.host == IntPtr.Zero)
+			{
+				throw new ENetException(0, "Host creation call failed.");
+			}
+
+			if (enableCrc)
+			{
+				this.EnableCrc();
+			}
+		}
+
+		public Task<Peer> ConnectAsync(
+				Address address, uint channelLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT, uint data = 0)
+		{
+			CheckChannelLimit(channelLimit);
+
+			var tcs = new TaskCompletionSource<Peer>();
+			ENetAddress nativeAddress = address.Struct;
+			IntPtr peerPtr = NativeMethods.enet_host_connect(this.host, ref nativeAddress, channelLimit, data);
+			if (peerPtr == IntPtr.Zero)
+			{
+				throw new ENetException(0, "Host connect call failed.");
+			}
+			var peer = new Peer(peerPtr);
+			this.PeersManager.Add(peerPtr, peer);
+			peer.PeerEvent.Connected += e =>
+			{
+				if (e.EventState == EventState.DISCONNECTED)
+				{
+					throw new ENetException(3, "Connect Disconnected!");
+				}
+				tcs.TrySetResult(peer);
+			};
+			return tcs.Task;
+		}
+
+		public void RunOnce(int timeout = 0)
+		{
+			this.OnExecuteEvents();
+
+			if (this.Service(timeout) < 0)
+			{
+				return;
+			}
+
+			Event ev;
+			while (this.CheckEvents(out ev) > 0)
+			{
+				switch (ev.Type)
+				{
+					case EventType.Connect:
+					{
+						Logger.Debug("client connect");
+						var peer = this.PeersManager[ev.PeerPtr];
+						peer.PeerEvent.OnConnected(ev);
+						peer.PeerEvent.Connected = null;
+						break;
+					}
+					case EventType.Receive:
+					{
+						Logger.Debug("client recv");
+						var peer = this.PeersManager[ev.PeerPtr];
+						peer.PeerEvent.OnReceived(ev);
+						peer.PeerEvent.Received = null;
+						break;
+					}
+					case EventType.Disconnect:
+					{
+						Logger.Debug("client disconnect");
+
+						ev.EventState = EventState.DISCONNECTED;
+						var peer = this.PeersManager[ev.PeerPtr];
+						if (peer.PeerEvent.Connected != null)
+						{
+							peer.PeerEvent.OnConnected(ev);
+						}
+						else if (peer.PeerEvent.Received != null)
+						{
+							peer.PeerEvent.OnReceived(ev);
+						}
+						else
+						{
+							peer.PeerEvent.OnDisconnect(ev);
+						}
+
+						this.PeersManager.Remove(ev.PeerPtr);
+						break;
+					}
+				}
+			}
+		}
+		
+		public void Run(int timeout = 0)
+		{
+			while (isRunning)
+			{
+				RunOnce(timeout);
+			}
+		}
+	}
+}

+ 8 - 0
CSharp/Platform/ENetCS/ENetCS.csproj

@@ -38,6 +38,7 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="Address.cs" />
+    <Compile Include="ClientHost.cs" />
     <Compile Include="ENetException.cs" />
     <Compile Include="Event.cs" />
     <Compile Include="Host.cs" />
@@ -48,10 +49,17 @@
     <Compile Include="NativeStructs.cs" />
     <Compile Include="Packet.cs" />
     <Compile Include="Peer.cs" />
+    <Compile Include="ServerHost.cs" />
   </ItemGroup>
   <ItemGroup>
     <Folder Include="Properties\" />
   </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Log\Log.csproj">
+      <Project>{72E16572-FC1F-4A9E-BC96-035417239298}</Project>
+      <Name>Log</Name>
+    </ProjectReference>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 

+ 27 - 19
CSharp/Platform/ENetCS/Event.cs

@@ -1,16 +1,35 @@
-namespace ENet
+using System;
+
+namespace ENet
 {
+	public enum EventState
+	{
+		CONNECTED = 0,
+		DISCONNECTED = 1,
+	}
+
 	public class Event
 	{
-		private readonly Host host;
 		private readonly ENetEvent ev;
+		private EventState peerState = EventState.CONNECTED;
 
-		public Event(Host host, ENetEvent ev)
+		public Event(ENetEvent ev)
 		{
-			this.host = host;
 			this.ev = ev;
 		}
 
+		public EventState EventState
+		{
+			get
+			{
+				return peerState;
+			}
+			set
+			{
+				peerState = value;
+			}
+		}
+
 		public ENetEvent Ev
 		{
 			get
@@ -19,30 +38,19 @@
 			}
 		}
 
-		public Packet Packet
+		public IntPtr PacketPtr
 		{
 			get
 			{
-				return new Packet(this.host, this.Ev.packet);
+				return Ev.packet;
 			}
 		}
 
-		public Peer Peer
+		public IntPtr PeerPtr
 		{
 			get
 			{
-				var peerPtr = this.Ev.peer;
-				if (!this.host.PeersManager.ContainsKey(this.Ev.peer))
-				{
-					var peer = new Peer(this.host, peerPtr);
-					this.host.PeersManager.Add(peerPtr, peer);
-					return peer;
-				}
-				else
-				{
-					Peer peer = this.host.PeersManager[peerPtr];
-					return peer;
-				}
+				return this.Ev.peer;
 			}
 		}
 

+ 17 - 139
CSharp/Platform/ENetCS/Host.cs

@@ -3,11 +3,11 @@ using System.Threading.Tasks;
 
 namespace ENet
 {
-	public sealed class Host: IDisposable
+	public abstract class Host: IDisposable
 	{
 		private readonly PeersManager peersManager = new PeersManager();
 
-		public PeersManager PeersManager
+		protected PeersManager PeersManager
 		{
 			get
 			{
@@ -15,73 +15,23 @@ namespace ENet
 			}
 		}
 
-		private IntPtr host;
-		private Action<Event> acceptHandler;
+		protected IntPtr host;
+		protected bool isRunning = true;
 		private readonly object eventsLock = new object();
 		private Action events;
-		private bool isRunning = true;
-
-		public Host(Address address, uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID, 
-				uint channelLimit = 0, uint incomingBandwidth = 0, 
-				uint outgoingBandwidth = 0, bool enableCrc = true)
-		{
-			if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
-			{
-				throw new ArgumentOutOfRangeException("peerLimit");
-			}
-			CheckChannelLimit(channelLimit);
-
-			ENetAddress nativeAddress = address.Struct;
-			this.host = NativeMethods.enet_host_create(
-					ref nativeAddress, peerLimit, 
-					channelLimit, incomingBandwidth, outgoingBandwidth);
-
-			if (this.host == IntPtr.Zero)
-			{
-				throw new ENetException(0, "Host creation call failed.");
-			}
-
-			if (enableCrc)
-			{
-				NativeMethods.enet_enable_crc(this.host);
-			}
-		}
-
-		public Host(uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID, 
-				uint channelLimit = 0, uint incomingBandwidth = 0,
-				uint outgoingBandwidth = 0, bool enableCrc = true)
-		{
-			if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
-			{
-				throw new ArgumentOutOfRangeException("peerLimit");
-			}
-			CheckChannelLimit(channelLimit);
-
-			this.host = NativeMethods.enet_host_create(IntPtr.Zero, peerLimit, channelLimit, incomingBandwidth, outgoingBandwidth);
-
-			if (this.host == IntPtr.Zero)
-			{
-				throw new ENetException(0, "Host creation call failed.");
-			}
-
-			if (enableCrc)
-			{
-				NativeMethods.enet_enable_crc(this.host);
-			}
-		}
-
+		
 		~Host()
 		{
 			this.Dispose(false);
 		}
 
-		public void Dispose()
+		public virtual void Dispose()
 		{
 			this.Dispose(true);
 			GC.SuppressFinalize(this);
 		}
 
-		private void Dispose(bool disposing)
+		protected void Dispose(bool disposing)
 		{
 			if (this.host == IntPtr.Zero)
 			{
@@ -93,7 +43,12 @@ namespace ENet
 			this.host = IntPtr.Zero;
 		}
 
-		private static void CheckChannelLimit(uint channelLimit)
+		protected void EnableCrc()
+		{
+			NativeMethods.enet_enable_crc(this.host);
+		}
+
+		protected static void CheckChannelLimit(uint channelLimit)
 		{
 			if (channelLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT)
 			{
@@ -101,15 +56,15 @@ namespace ENet
 			}
 		}
 
-		private int CheckEvents(out Event e)
+		protected int CheckEvents(out Event e)
 		{
 			var enetEv = new ENetEvent();
 			int ret = NativeMethods.enet_host_check_events(this.host, enetEv);
-			e = new Event(this, enetEv);
+			e = new Event(enetEv);
 			return ret;
 		}
 
-		private int Service(int timeout)
+		protected int Service(int timeout)
 		{
 			if (timeout < 0)
 			{
@@ -133,34 +88,6 @@ namespace ENet
 			NativeMethods.enet_host_compress(this.host, IntPtr.Zero);
 		}
 
-		public Task<Peer> ConnectAsync(
-				Address address, uint channelLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_CHANNEL_COUNT, uint data = 0)
-		{
-			CheckChannelLimit(channelLimit);
-
-			var tcs = new TaskCompletionSource<Peer>();
-			ENetAddress nativeAddress = address.Struct;
-			IntPtr p = NativeMethods.enet_host_connect(this.host, ref nativeAddress, channelLimit, data);
-			if (p == IntPtr.Zero)
-			{
-				throw new ENetException(0, "Host connect call failed.");
-			}
-			var peer = new Peer(this, p);
-			this.PeersManager[p].PeerEvent.Connected += e => tcs.TrySetResult(peer);
-			return tcs.Task;
-		}
-
-		public Task<Peer> AcceptAsync()
-		{
-			if (acceptHandler != null)
-			{
-				throw new ENetException(0, "don't accept twice, when last accept not return!");
-			}
-			var tcs = new TaskCompletionSource<Peer>();
-			acceptHandler += e => tcs.TrySetResult(e.Peer);
-			return tcs.Task;
-		}
-
 		public void Flush()
 		{
 			NativeMethods.enet_host_flush(this.host);
@@ -195,7 +122,7 @@ namespace ENet
 			}
 		}
 
-		private void OnExecuteEvents()
+		protected void OnExecuteEvents()
 		{
 			Action local = null;
 			lock (this.eventsLock)
@@ -214,54 +141,5 @@ namespace ENet
 		{
 			isRunning = false;
 		}
-
-		public void Run(int timeout = 0)
-		{
-			while (isRunning)
-			{
-				this.OnExecuteEvents();
-
-				if (this.Service(timeout) < 0)
-				{
-					continue;
-				}
-
-				Event ev;
-				while (this.CheckEvents(out ev) > 0)
-				{
-					switch (ev.Type)
-					{
-						case EventType.Connect:
-						{
-							// 如果PeersManager包含了peer,则这次是connect事件
-							// 反之是accept事件
-							if (this.PeersManager.ContainsKey(ev.Ev.peer))
-							{
-								ev.Peer.PeerEvent.OnConnected(ev);
-							}
-							else
-							{
-								if (acceptHandler != null)
-								{
-									acceptHandler(ev);
-									acceptHandler = null;
-								}
-							}
-							break;
-						}
-						case EventType.Receive:
-						{
-							ev.Peer.PeerEvent.OnReceived(ev);
-							break;
-						}
-						case EventType.Disconnect:
-						{
-							ev.Peer.PeerEvent.OnDisconnect(ev);
-							break;
-						}
-					}
-				}
-			}
-		}
 	}
 }

+ 1 - 3
CSharp/Platform/ENetCS/Packet.cs

@@ -6,12 +6,10 @@ namespace ENet
 {
 	public sealed class Packet: IDisposable
 	{
-		private Host host;
 		private IntPtr packet;
 
-		public Packet(Host host, IntPtr packet)
+		public Packet(IntPtr packet)
 		{
-			this.host = host;
 			this.packet = packet;
 		}
 

+ 12 - 8
CSharp/Platform/ENetCS/Peer.cs

@@ -4,17 +4,14 @@ using System.Threading.Tasks;
 
 namespace ENet
 {
-	public class Peer: IDisposable
+	public sealed class Peer: IDisposable
 	{
-		private readonly Host host;
 		private readonly PeerEvent peerEvent = new PeerEvent();
 		private IntPtr peer;
 
-		public Peer(Host host, IntPtr peer)
+		public Peer(IntPtr peer)
 		{
-			this.host = host;
 			this.peer = peer;
-			host.PeersManager.Add(peer, this);
 		}
 
 		~Peer()
@@ -28,14 +25,13 @@ namespace ENet
 			GC.SuppressFinalize(this);
 		}
 
-		protected virtual void Dispose(bool disposing)
+		private void Dispose(bool disposing)
 		{
 			if (this.peer == IntPtr.Zero)
 			{
 				return;
 			}
 
-			this.host.PeersManager.Remove(this.peer);
 			NativeMethods.enet_peer_reset(this.peer);
 			this.peer = IntPtr.Zero;
 		}
@@ -102,7 +98,15 @@ namespace ENet
 		public Task<Packet> ReceiveAsync()
 		{
 			var tcs = new TaskCompletionSource<Packet>();
-			this.PeerEvent.Received += e => tcs.TrySetResult(e.Packet);
+			this.PeerEvent.Received += e =>
+			{
+				if (e.EventState == EventState.DISCONNECTED)
+				{
+					throw new ENetException(3, "connect disconnected!");
+				}
+				var packet = new Packet(e.PacketPtr);
+				tcs.TrySetResult(packet);
+			};
 			return tcs.Task;
 		}
 

+ 15 - 15
CSharp/Platform/ENetCS/PeerEvent.cs

@@ -8,39 +8,39 @@ namespace ENet
 		private Action<Event> received;
 		private Action<Event> disconnect;
 
-		public event Action<Event> Connected
+		public Action<Event> Connected
 		{
-			add
+			get
 			{
-				this.connected += value;
+				return this.connected;
 			}
-			remove
+			set
 			{
-				this.connected -= value;
+				this.connected = value;
 			}
 		}
 
-		public event Action<Event> Received
+		public Action<Event> Received
 		{
-			add
+			get
 			{
-				this.received += value;
+				return this.received;
 			}
-			remove
+			set
 			{
-				this.received -= value;
+				this.received = value;
 			}
 		}
 
-		public event Action<Event> Disconnect
+		public Action<Event> Disconnect
 		{
-			add
+			get
 			{
-				this.disconnect += value;
+				return this.disconnect;
 			}
-			remove
+			set
 			{
-				this.disconnect -= value;
+				this.disconnect = value;
 			}
 		}
 

+ 122 - 0
CSharp/Platform/ENetCS/ServerHost.cs

@@ -0,0 +1,122 @@
+using System;
+using System.Threading.Tasks;
+using Log;
+
+namespace ENet
+{
+	public sealed class ServerHost : Host
+	{
+		private Action<Event> acceptHandler;
+
+		public ServerHost(Address address, uint peerLimit = NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID,
+				uint channelLimit = 0, uint incomingBandwidth = 0,
+				uint outgoingBandwidth = 0, bool enableCrc = true)
+		{
+			if (peerLimit > NativeMethods.ENET_PROTOCOL_MAXIMUM_PEER_ID)
+			{
+				throw new ArgumentOutOfRangeException("peerLimit");
+			}
+			CheckChannelLimit(channelLimit);
+
+			ENetAddress nativeAddress = address.Struct;
+			this.host = NativeMethods.enet_host_create(
+					ref nativeAddress, peerLimit,
+					channelLimit, incomingBandwidth, outgoingBandwidth);
+
+			if (this.host == IntPtr.Zero)
+			{
+				throw new ENetException(0, "Host creation call failed.");
+			}
+
+			if (enableCrc)
+			{
+				NativeMethods.enet_enable_crc(this.host);
+			}
+		}
+
+		public Task<Peer> AcceptAsync()
+		{
+			if (acceptHandler != null)
+			{
+				throw new ENetException(0, "don't accept twice, when last accept not return!");
+			}
+			var tcs = new TaskCompletionSource<Peer>();
+			acceptHandler += e =>
+			{
+				if (e.EventState == EventState.DISCONNECTED)
+				{
+					throw new ENetException(3, "Connect Disconnected!");
+				}
+				var peer = new Peer(e.PeerPtr);
+				this.PeersManager.Add(e.PeerPtr, peer);
+				tcs.TrySetResult(peer);
+			};
+			return tcs.Task;
+		}
+
+		public void RunOnce(int timeout = 0)
+		{
+			this.OnExecuteEvents();
+
+			if (this.Service(timeout) < 0)
+			{
+				return;
+			}
+
+			Event ev;
+			while (this.CheckEvents(out ev) > 0)
+			{
+				switch (ev.Type)
+				{
+					case EventType.Connect:
+					{
+						Logger.Debug("server connect");
+						if (acceptHandler != null)
+						{
+							acceptHandler(ev);
+							acceptHandler = null;
+						}
+						break;
+					}
+					case EventType.Receive:
+					{
+						Logger.Debug("server recv");
+						var peer = this.PeersManager[ev.PeerPtr];
+						peer.PeerEvent.OnReceived(ev);
+						peer.PeerEvent.Received = null;
+						break;
+					}
+					case EventType.Disconnect:
+					{
+						Logger.Debug("server disconnect");
+						ev.EventState = EventState.DISCONNECTED;
+						var peer = this.PeersManager[ev.PeerPtr];
+						if (acceptHandler != null)
+						{
+							acceptHandler(ev);
+						}
+						else if (peer.PeerEvent.Received != null)
+						{
+							peer.PeerEvent.OnReceived(ev);
+						}
+						else
+						{
+							peer.PeerEvent.OnDisconnect(ev);
+						}
+
+						this.PeersManager.Remove(ev.PeerPtr);
+						break;
+					}
+				}
+			}
+		}
+
+		public void Run(int timeout = 0)
+		{
+			while (isRunning)
+			{
+				RunOnce(timeout);
+			}
+		}
+	}
+}

+ 4 - 0
CSharp/PlatformTest/ENetCSTest/ENetCSTest.csproj

@@ -61,6 +61,10 @@
       <Project>{D0B4CFAC-A368-4742-9863-68776CFA9938}</Project>
       <Name>ENetCS</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\Platform\Log\Log.csproj">
+      <Project>{72e16572-fc1f-4a9e-bc96-035417239298}</Project>
+      <Name>Log</Name>
+    </ProjectReference>
   </ItemGroup>
   <Choose>
     <When Condition="'$(VisualStudioVersion)' == '10.0' And '$(IsCodedUITest)' == 'True'">

+ 21 - 7
CSharp/PlatformTest/ENetCSTest/ENetClientServerTest.cs

@@ -1,7 +1,6 @@
-using System;
-using System.Threading;
-using System.Windows.Threading;
+using System.Threading;
 using ENet;
+using Log;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
 namespace ENetCSTest
@@ -9,28 +8,41 @@ namespace ENetCSTest
 	[TestClass]
 	public class ENetClientServerTest
 	{
-		private static async void Connect(Host host, Address address)
+		private static async void Connect(ClientHost host, Address address)
 		{
+			Logger.Debug("Connect");
 			var peer = await host.ConnectAsync(address);
+			Logger.Debug("Connect OK");
 			var sPacket = new Packet("0123456789", PacketFlags.Reliable);
 			peer.Send(0, sPacket);
+			Logger.Debug("Send OK");
 			var rPacket = await peer.ReceiveAsync();
+			Logger.Debug("Receive OK");
 
 			Assert.AreEqual("9876543210", rPacket.Bytes.ToString());
 
 			await peer.DisconnectLaterAsync();
+			Logger.Debug("Disconnect OK");
+
+			host.Stop();
 		}
 
-		private static async void Accept(Host host)
+		private static async void Accept(ServerHost host)
 		{
+			Logger.Debug("Accept");
 			var peer = await host.AcceptAsync();
+			Logger.Debug("Accept OK");
 			var rPacket = await peer.ReceiveAsync();
+			Logger.Debug("Receive OK");
 
 			Assert.AreEqual("0123456789", rPacket.Bytes.ToString());
 
 			var sPacket = new Packet("9876543210", PacketFlags.Reliable);
 			peer.Send(0, sPacket);
+			Logger.Debug("Send OK");
 			await peer.DisconnectLaterAsync();
+
+			host.Stop();
 		}
 
 		[TestMethod]
@@ -39,8 +51,8 @@ namespace ENetCSTest
 			Library.Initialize();
 
 			var address = new Address { HostName = "127.0.0.1", Port = 8888 };
-			var serverHost = new Host();
-			var clientHost = new Host(address);
+			var clientHost = new ClientHost();
+			var serverHost = new ServerHost(address);
 
 			var server = new Thread(() => serverHost.Run(10));
 			var client = new Thread(() => clientHost.Run(10));
@@ -52,6 +64,8 @@ namespace ENetCSTest
 
 			server.Join();
 			client.Join();
+
+			Library.Deinitialize();
 		}
 	}
 }