lnicola
6/26/2014 - 12:05 PM

AsyncTest.cs

using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;

namespace AsyncTest
{
	struct AsyncThread
	{
		public static void Start<T>(Func<Func<IEnumerator>, T, IEnumerator> operation, T argument)
		{
			IEnumerator enumerator = null;
			enumerator = operation(() => enumerator, argument);
			enumerator.MoveNext();
		}
	}

	class Test
	{
		public Test()
		{
			var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			s.Bind(new IPEndPoint(IPAddress.Any, 42));
			s.Listen(1);

			AsyncThread.Start(AsyncAccept, s);
		}

		IEnumerator AsyncAccept(Func<IEnumerator> getEnumerator, Socket s)
		{
			var enumerator = getEnumerator();
			IAsyncResult iar;
			while (true)
			{
				yield return iar = s.BeginAccept(_ => enumerator.MoveNext(), null);
				AsyncThread.Start(AsyncProcessClient, s.EndAccept(iar));
			}
		}

		IEnumerator AsyncProcessClient(Func<IEnumerator> getEnumerator, Socket cs)
		{
			var enumerator = getEnumerator();
			Console.WriteLine("Client connected");

			var buf = new byte[1024];
			IAsyncResult iar;
			SocketError error;
			while (true)
			{
				yield return iar = cs.BeginReceive(buf, 0, buf.Length, SocketFlags.None, _ => enumerator.MoveNext(), null);
				var len = cs.EndReceive(iar, out error);
				if (error != SocketError.Success)
					yield break;

				Console.WriteLine("Received: {0} bytes", len);

				var offset = 0;
				while (offset < len)
				{
					yield return iar = cs.BeginSend(buf, offset, len - offset, SocketFlags.None, _ => enumerator.MoveNext(), null);
					offset += cs.EndSend(iar, out error);
					if (error != SocketError.Success)
						yield break;
				}
			}
		}
	}

	static class Program
	{
		static void Main()
		{
			new Test();
			Console.ReadLine();
		}
	}
}
using System;
using System.Collections;
using System.Net;
using System.Net.Sockets;

namespace AsyncTest
{
	struct AsyncThread
	{
		public static void Start<T>(Func<AsyncCallback, T, IEnumerator> operation, T argument)
		{
			IEnumerator enumerator = null;
			enumerator = operation(_ => enumerator.MoveNext(), argument);
			enumerator.MoveNext();
		}

		public static void Call<T>(Func<AsyncCallback, T, IEnumerator> operation, AsyncCallback callback, T argument)
		{
			IEnumerator enumerator = null;
			enumerator = operation(_ => { if (!enumerator.MoveNext()) callback(null); }, argument);
			enumerator.MoveNext();
		}
	}

	class Test
	{
		public Test()
		{
			var s = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
			s.Bind(new IPEndPoint(IPAddress.Any, 42));
			s.Listen(1);

			AsyncThread.Start(AsyncAccept, s);
		}

		IEnumerator AsyncAccept(AsyncCallback asyncCallback, Socket s)
		{
			IAsyncResult iar;
			while (true)
			{
				yield return iar = s.BeginAccept(asyncCallback, null);
				AsyncThread.Start(AsyncProcessClient, s.EndAccept(iar));
			}
		}

		IEnumerator AsyncProcessClient(AsyncCallback asyncCallback, Socket cs)
		{
			Console.WriteLine("Client connected");

			var buf = new byte[1024];
			IAsyncResult iar;
			SocketError error;
			while (true)
			{
				yield return iar = cs.BeginReceive(buf, 0, buf.Length, SocketFlags.None, asyncCallback, null);
				var len = cs.EndReceive(iar, out error);
				if (error != SocketError.Success)
					yield break;

				Console.WriteLine("Received: {0} bytes", len);

				var offset = 0;
				while (offset < len)
				{
					yield return iar = cs.BeginSend(buf, offset, len - offset, SocketFlags.None, asyncCallback, null);
					offset += cs.EndSend(iar, out error);
					if (error != SocketError.Success)
						yield break;
				}
			}
		}
	}

	static class Program
	{
		static void Main()
		{
			new Test();
			Console.ReadLine();
		}
	}
}