// main method // call this method to start the server public void StartListening() { m_MarineExchangeDB = new MarineExchangeEntities(); IPHostEntry ipHostInfo = new IPHostEntry(); ipHostInfo.AddressList = new IPAddress[] { _serverIP }; IPAddress ipAddress = ipHostInfo.AddressList[0]; IPEndPoint localEndPoint = new IPEndPoint(ipAddress, _serverPortNumber); // Create a TCP/IP socket. Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); // client threads List<Thread> listOfThreads = new List<Thread>(); _clients = new List<AsynchronousClient>(); // connect to feeds configured in database SetupFeeds(); if (_feeds.Count() > 0) { Thread transferBufferThread = new Thread(() => CheckFeedBuffer()); transferBufferThread.Start(); // start the listener socket try { listener.Bind(localEndPoint); listener.Listen(100); // will continue to run as long as the thread which is transferring while (transferBufferThread.IsAlive && _feeds.Count > 0) { // reset _addDone - will be set again in BeginAccept _allDone.Reset(); Socket newSocket = null; EntireConnection newConnection; try { newConnection = (EntireConnection)listener.BeginAccept(new AsyncCallback(ServerAcceptCallback), new EntireConnection { serverSocket = listener, clientSocket = newSocket }).AsyncState; } catch (Exception ex) { m_MarineExchangeDB.LogError(ex.Message, ex.StackTrace, "AsynchronousSocketListener.StartListening", ex.InnerException.ToString(), ex.TargetSite.ToString(), DateTime.Now, null, null, null); newConnection = null; } // wait till accept is complete _allDone.WaitOne(); if (newConnection != null) { try { // create new client - client has own thread which starts processing AsynchronousClient newClient = new AsynchronousClient(newConnection.clientSocket); _clients.Add(newClient); } catch (Exception ex) { m_MarineExchangeDB.LogError(ex.Message, ex.StackTrace, "AsynchronousSocketListener.StartListening", ex.InnerException.ToString(), ex.TargetSite.ToString(), DateTime.Now, null, null, null); } } } } catch (Exception ex) { m_MarineExchangeDB.LogError(ex.Message, ex.StackTrace, "AsynchronousSocketListener.StartListening", ex.InnerException.ToString(), ex.TargetSite.ToString(), DateTime.Now, null, null, null); } } }
// this method accepts a client socket and begins sending data to that client private static void ServerSend(AsynchronousClient client) { Socket handler = client.ClientSocket; byte[] data = null; lock (feed.sb) { data = Encoding.ASCII.GetBytes(feed.sb.ToString()); feed.sb.Clear(); } if (data != null) handler.BeginSend(data, 0, data.Length, 0, new AsyncCallback(ServerSendCallback), client); }
// used to accept a new client connection // this method should be called as part of the creation of a new thread private static void ServerAcceptCallback(IAsyncResult ar) { // signal the main thread to continue (move this to after the EndAccept?) lock (_allDone) { _allDone.Set(); } // retrieve the listener socket Socket listener = (Socket)ar.AsyncState; // retrieve the new socket created for this connect Socket clientSocket = listener.EndAccept(ar); // use the created socket as the basis for the new client (new AsynchronousClient) AsynchronousClient newClient = new AsynchronousClient(); newClient.ClientSocket = clientSocket; newClient.sendDone.Reset(); // call client's method to BeginReceive clientSocket.BeginReceive(newClient.buffer, 0, 1024, 0, new AsyncCallback(ServerReceiveCallback), newClient); newClient.sendDone.WaitOne(); // once the client has identified itself, begin sending data while (newClient.ClientSocket.Connected) { ServerSend(newClient); } }
// this method accepts a client socket and begins sending data to that client private void ServerSend(AsynchronousClient client) { Socket handler = client.ClientSocket; byte[] data = null; lock (LocalBuffer) { data = Encoding.ASCII.GetBytes(LocalBuffer); LocalBuffer = string.Empty; } if (data != null) { try { handler.BeginSend(data, 0, data.Length, 0, new AsyncCallback(ServerSendCallback), client); } catch (Exception ex) { // response to any socket errors is to close the connection handler.Close(); m_MarineExchangeDB.LogError(ex.Message, ex.StackTrace, "AsynchronousClient.Start", ex.InnerException.ToString(), ex.TargetSite.ToString(), DateTime.Now, null, ClientID, DeviceID); m_MarineExchangeDB.LogCloseConnection(AccessIP, ClientID, DeviceID); } } }