Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- namespace SocketServer
- {
- static class Program
- {
- private const char LengthPrefixDelimiter = ';';
- private static AutoResetEvent _flipFlop = new AutoResetEvent(false);
- static void Main(string[] args)
- {
- // create a socket
- Socket listener = new Socket(AddressFamily.InterNetwork,
- SocketType.Stream,
- ProtocolType.Tcp);
- // create a local endpoint
- IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
- IPEndPoint localEP = new IPEndPoint(ipHostInfo.AddressList.First(), 22222);
- Console.WriteLine("Local address and port : {0}", localEP);
- // bind and listen
- try
- {
- listener.Bind(localEP);
- listener.Listen(1);
- while (true)
- {
- Console.WriteLine("Waiting for the next connection...");
- // accept the next connection
- listener.BeginAccept(AcceptCallback, listener);
- _flipFlop.WaitOne();
- }
- }
- catch (Exception e)
- {
- Console.WriteLine(e.ToString());
- }
- listener.Accept();
- listener.Listen(1);
- }
- private static void AcceptCallback(IAsyncResult ar)
- {
- // retrieve the listener, accept
- var listener = (Socket)ar.AsyncState;
- var socket = listener.EndAccept(ar);
- Console.WriteLine("Connected a client.");
- // trigger new listen
- _flipFlop.Set();
- // start receiving
- var state = new StateObject();
- state.Socket = socket;
- socket.BeginReceive(state.Buffer,
- 0,
- StateObject.BufferSize,
- 0,
- ReceiveCallback,
- state);
- }
- private static void ReceiveCallback(IAsyncResult ar)
- {
- // retrieve the state and socket
- StateObject state = (StateObject)ar.AsyncState;
- Socket socket = state.Socket;
- // Read data from the client socket.
- int read = socket.EndReceive(ar);
- // flag to indicate there's more data coming
- bool allRead = true;
- // Data was read from the client socket.
- if (read > 0)
- {
- // convert result and output
- string chunk = Encoding.UTF8.GetString(state.Buffer, 0, read);
- state.StringBuilder.Append(chunk);
- // here's our small protocol implementation: check the length-prefix
- string messageLengthText = state.StringBuilder.SubstringByDelimiter(LengthPrefixDelimiter);
- if (state.TotalSize == 0)
- {
- if (!string.IsNullOrEmpty(messageLengthText))
- {
- // get length and set total size
- var messageLength = Convert.ToInt32(messageLengthText);
- state.TotalSize = messageLength;
- }
- else
- {
- // if we haven't received the delimiter yet (very unlikely),
- // simply continue reading
- allRead = false;
- }
- }
- // simply check if we've read all bytes
- allRead = allRead && state.StringBuilder.Length - messageLengthText.Length - 1 == state.TotalSize;
- }
- // check if we need to listen again
- if (!allRead)
- {
- // receive again
- socket.BeginReceive(state.Buffer,
- 0,
- StateObject.BufferSize,
- 0,
- ReceiveCallback,
- state);
- }
- else
- {
- // output anything we've received
- if (state.StringBuilder.Length > 0)
- {
- // prepare result
- string result = state.StringBuilder.ToString();
- result = result.Substring(result.IndexOf(LengthPrefixDelimiter) + 1);
- // output result on console
- Console.WriteLine("Received a message: {0}", result);
- }
- socket.Shutdown(SocketShutdown.Both);
- socket.Close();
- Console.WriteLine("Closed client connection.");
- }
- }
- public static string SubstringByDelimiter(this StringBuilder sb, char delimiter)
- {
- StringBuilder result = new StringBuilder(sb.Length);
- for (int i = 0; i < sb.Length; i++)
- {
- if (sb[i] == delimiter)
- {
- return result.ToString();
- }
- result.Append(sb[i]);
- }
- return string.Empty;
- }
- }
- public class StateObject
- {
- public Socket Socket;
- public StringBuilder StringBuilder = new StringBuilder();
- public const int BufferSize = 10;
- public byte[] Buffer = new byte[BufferSize];
- public int TotalSize;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement