From c0dbd29dfe66ea2e75d3b67b742bdb1505e88153 Mon Sep 17 00:00:00 2001 From: AJ ONeal Date: Mon, 6 Aug 2012 15:49:49 -0600 Subject: [PATCH] added tcp echo in c-sharp (not my own work) --- tcp-echo-csharp/AssemblyInfo.cs | 27 +++++ tcp-echo-csharp/Main.cs | 168 ++++++++++++++++++++++++++++++++ tcp-echo-csharp/echo.csproj | 42 ++++++++ tcp-echo-csharp/echo.sln | 20 ++++ 4 files changed, 257 insertions(+) create mode 100644 tcp-echo-csharp/AssemblyInfo.cs create mode 100644 tcp-echo-csharp/Main.cs create mode 100644 tcp-echo-csharp/echo.csproj create mode 100644 tcp-echo-csharp/echo.sln diff --git a/tcp-echo-csharp/AssemblyInfo.cs b/tcp-echo-csharp/AssemblyInfo.cs new file mode 100644 index 0000000..bdcdea0 --- /dev/null +++ b/tcp-echo-csharp/AssemblyInfo.cs @@ -0,0 +1,27 @@ +using System.Reflection; +using System.Runtime.CompilerServices; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("echo")] +[assembly: AssemblyDescription("")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany("")] +[assembly: AssemblyProduct("")] +[assembly: AssemblyCopyright("coolaj86")] +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion("1.0.*")] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + diff --git a/tcp-echo-csharp/Main.cs b/tcp-echo-csharp/Main.cs new file mode 100644 index 0000000..155f744 --- /dev/null +++ b/tcp-echo-csharp/Main.cs @@ -0,0 +1,168 @@ +// http://msdn.microsoft.com/en-us/library/fx6588te(v=vs.80).aspx +using System; +using System.Net; +using System.Net.Sockets; +using System.Text; +using System.Threading; + +namespace echo +{ + // State object for reading client data asynchronously + public class StateObject { + // Client socket. + public Socket workSocket = null; + // Size of receive buffer. + public const int BufferSize = 64 * 1024; + // Receive buffer. + public byte[] buffer = new byte[BufferSize]; + // Received data string. + public StringBuilder sb = new StringBuilder(); + } + + public class AsynchronousSocketListener { + // Thread signal. + public static ManualResetEvent allDone = new ManualResetEvent(false); + + public AsynchronousSocketListener() { + } + + public static void StartListening() { + UInt16 port = 11000; + UInt16 maxConnections = 100; + + // Establish the local endpoint for the socket. + // The DNS name of the computer + // running the listener is "host.contoso.com". + IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName()); + IPAddress ipAddress = ipHostInfo.AddressList[0]; + IPEndPoint localEndPoint = new IPEndPoint(ipAddress, port); + + // Create a TCP/IP socket. + Socket listener = new Socket(AddressFamily.InterNetwork, + SocketType.Stream, ProtocolType.Tcp ); + + // Bind the socket to the local endpoint and listen for incoming connections. + try { + listener.Bind(localEndPoint); + listener.Listen(maxConnections); + + Console.WriteLine("Listening on {0}:{1}", ipAddress, port); + + while (true) { + // Set the event to nonsignaled state. + allDone.Reset(); + + // Start an asynchronous socket to listen for connections. + Console.WriteLine("Waiting for a connection..."); + listener.BeginAccept( + new AsyncCallback(AcceptCallback), + listener ); + + // Wait until a connection is made before continuing. + allDone.WaitOne(); + } + + } catch (Exception e) { + Console.WriteLine(e.ToString()); + } + + Console.WriteLine("\nPress ENTER to continue..."); + Console.Read(); + } + + public static void AcceptCallback(IAsyncResult ar) { + // Signal the main thread to continue. + allDone.Set(); + + // Get the socket that handles the client request. + Socket listener = (Socket) ar.AsyncState; + Socket handler = listener.EndAccept(ar); + + // Create the state object. + StateObject state = new StateObject(); + state.workSocket = handler; + try { + handler.BeginReceive( state.buffer, 0, StateObject.BufferSize, 0, + new AsyncCallback(ReadCallback), state); + } catch(Exception e) { + Console.WriteLine ("oh dear"); + Console.WriteLine(e.ToString()); + } + } + + public static void ReadCallback(IAsyncResult ar) { + String content = String.Empty; + + // Retrieve the state object and the handler socket + // from the asynchronous state object. + StateObject state = (StateObject) ar.AsyncState; + Socket handler = state.workSocket; + + // Read data from the client socket. + int bytesRead; + try { + bytesRead = handler.EndReceive(ar); + } catch (Exception e) { + Console.WriteLine ("Client already disconnected " + e.ToString()); + return; + } + + if (bytesRead > 0) { + Console.WriteLine ("some bytes read"); + // There might be more data, so store the data received so far. + state.sb.Append(Encoding.ASCII.GetString( + state.buffer,0,bytesRead)); + + // Check for end-of-file tag. If it is not there, read + // more data. + content = state.sb.ToString(); + if (content.IndexOf("") > -1) { + // All the data has been read from the + // client. Display it on the console. + Console.WriteLine("Read {0} bytes from socket. \n Data : {1}", + content.Length, content ); + // Echo the data back to the client. + Send(handler, content); + } else { + // Not all data received. Get more. + handler.BeginReceive(state.buffer, 0, StateObject.BufferSize, 0, + new AsyncCallback(ReadCallback), state); + } + } else { + Console.WriteLine ("0 bytes read"); + } + } + + private static void Send(Socket handler, String data) { + // Convert the string data to byte data using ASCII encoding. + byte[] byteData = Encoding.ASCII.GetBytes(data); + + // Begin sending the data to the remote device. + handler.BeginSend(byteData, 0, byteData.Length, 0, + new AsyncCallback(SendCallback), handler); + } + + private static void SendCallback(IAsyncResult ar) { + try { + // Retrieve the socket from the state object. + Socket handler = (Socket) ar.AsyncState; + + // Complete sending the data to the remote device. + int bytesSent = handler.EndSend(ar); + Console.WriteLine("Sent {0} bytes to client.", bytesSent); + + handler.Shutdown(SocketShutdown.Both); + handler.Close(); + + } catch (Exception e) { + Console.WriteLine(e.ToString()); + } + } + + + public static int Main(String[] args) { + StartListening(); + return 0; + } + } +} diff --git a/tcp-echo-csharp/echo.csproj b/tcp-echo-csharp/echo.csproj new file mode 100644 index 0000000..94b9f7c --- /dev/null +++ b/tcp-echo-csharp/echo.csproj @@ -0,0 +1,42 @@ + + + + Debug + x86 + 9.0.21022 + 2.0 + {3F6FA1C0-DF5D-4F8C-BD3C-2DD5F0D911C5} + Exe + echo + echo + v3.5 + + + true + full + false + bin\Debug + DEBUG; + prompt + 4 + x86 + true + + + none + true + bin\Release + prompt + 4 + x86 + true + + + + + + + + + + \ No newline at end of file diff --git a/tcp-echo-csharp/echo.sln b/tcp-echo-csharp/echo.sln new file mode 100644 index 0000000..5a5abc0 --- /dev/null +++ b/tcp-echo-csharp/echo.sln @@ -0,0 +1,20 @@ + +Microsoft Visual Studio Solution File, Format Version 10.00 +# Visual Studio 2008 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "echo", "echo.csproj", "{3F6FA1C0-DF5D-4F8C-BD3C-2DD5F0D911C5}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x86 = Debug|x86 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {3F6FA1C0-DF5D-4F8C-BD3C-2DD5F0D911C5}.Debug|x86.ActiveCfg = Debug|x86 + {3F6FA1C0-DF5D-4F8C-BD3C-2DD5F0D911C5}.Debug|x86.Build.0 = Debug|x86 + {3F6FA1C0-DF5D-4F8C-BD3C-2DD5F0D911C5}.Release|x86.ActiveCfg = Release|x86 + {3F6FA1C0-DF5D-4F8C-BD3C-2DD5F0D911C5}.Release|x86.Build.0 = Release|x86 + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = echo.csproj + EndGlobalSection +EndGlobal