private void OnClientConnect(IAsyncResult asyn) { try { if (!_isListening) { return; } Socket socket = _listener.EndAccept(asyn); if (socket == null) { return; } int id = SocketHelper.GetNewSocketID(); ISocketWorker worker = SocketWorkerFactory.Create(id, socket, this); if (worker == null) { SocketLogMgt.SetLog(SocketLogType.Error, this, "Create socket worker failed."); return; } worker.Open(); //_listener.BeginAccept(new AsyncCallback(OnClientConnect), null); } catch (Exception err) { SocketLogMgt.SetLastError(err); } finally { _listener.BeginAccept(new AsyncCallback(OnClientConnect), null); } }
public bool Start() { bool result; SocketLogMgt.SetLog(this, "============================================="); SocketLogMgt.SetLog(this, ": Start Socket Listening."); SocketLogMgt.SetLog(this, Config); try { if (_config.EnableConnectionCollecting) { _timer.Start(); } _listener.SendTimeout = _config.SendTimeout; _listener.ReceiveTimeout = _config.ReceiveTimeout; _listener.Listen(_config.BackLog); _listener.BeginAccept(new AsyncCallback(OnClientConnect), null); _isListening = true; result = true; } catch (Exception err) { SocketLogMgt.SetLastError(err); _isListening = false; result = false; } SocketLogMgt.SetLog(this, ": Start Socket Listening Result: " + result.ToString()); SocketLogMgt.SetLog(this, "=============================================\r\n"); return(result); }
public bool Stop() { bool result; SocketLogMgt.SetLog(this, "============================================="); SocketLogMgt.SetLog(this, ": Stop Socket Listening."); try { if (_timer.Enabled) { _timer.Stop(); } _isListening = false; _listener.Close(); ClearWorkers(); result = true; } catch (Exception err) { SocketLogMgt.SetLastError(err); result = false; } SocketLogMgt.SetLog(this, ": Stop Socket Listening Result: " + result.ToString()); SocketLogMgt.SetLog(this, "=============================================\r\n"); return(result); }
private void OnDataSent(IAsyncResult asyn) { try { if (_isClosed) { SocketLogMgt.SetLog(SocketLogType.Warning, this, "Data sent, but the socket is closed."); return; } int bytesSent = _socket.EndSend(asyn); SocketLogMgt.SetLog(this, _strSocketID + "Sent succeeded. " + bytesSent.ToString() + " bytes."); UpdateActiveDT(); //// if not allow multiple session per connection, then close server socket after the first acknowledgement is sent. //if (!_server.Config.AllowMultipleSessionPerConnection) Close(); } catch (SocketException err) { SocketLogMgt.SetLastError(err); // if client disconnected or other network exception when sending data, then close the server socket. CloseWorker(); } catch (Exception e) { SocketLogMgt.SetLastError(e); // if communication is ok, but process message failed, do not need to close connection. } }
public static IServer Create(SocketServerConfig config) { try { int port = config.Port; string ip = config.IPAddress; Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); SocketKeepAliveHelper.SetKeepAliveValues(config, listener, config); if (ip == null || ip.Length < 1 || ip == "127.0.0.1") { listener.Bind(new IPEndPoint(IPAddress.Any, port)); } else { listener.Bind(new IPEndPoint(IPAddress.Parse(ip), port)); } return(new SocketServer(listener, config)); } catch (Exception err) { SocketLogMgt.SetLastError(err); return(null); } }
private void OnDataSent(IAsyncResult asyn) { try { int bytesSent = _socket.EndSend(asyn); SocketLogMgt.SetLog(_socketID + "Sent succeeded. " + bytesSent.ToString() + " bytes."); _allDone.Set(); } catch (Exception err) { SocketLogMgt.SetLastError(this, err); } }
private bool _isClosed; // for performance consideration, do not lock this field currently. private void OpenWorker() { try { _server.AddWorker(this); SocketLogMgt.SetLog(this, "============================================="); SocketLogMgt.SetLog(this, ": Client Connected from: " + _remoteEndPointInfo); SocketLogMgt.SetLog(this, ": Worker Socket Created. ID: " + _strSocketID); ReceiveData(); } catch (Exception err) { SocketLogMgt.SetLastError(err); } }
public static IServer Create(int port) { try { SocketServerConfig cfg = new SocketServerConfig(); cfg.Port = port; Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); SocketKeepAliveHelper.SetKeepAliveValues(cfg, listener, cfg); listener.Bind(new IPEndPoint(IPAddress.Any, port)); return(new SocketServer(listener, cfg)); } catch (Exception err) { SocketLogMgt.SetLastError(err); return(null); } }
public static System.Text.Encoding GetEncoder(ICodePageIndicator codePage) { try { if (codePage.CodePageCode < 0) { return(System.Text.Encoding.GetEncoding(codePage.CodePageName)); } else { return(System.Text.Encoding.GetEncoding(codePage.CodePageCode)); } } catch (Exception err) { SocketLogMgt.SetLastError(err); return(System.Text.Encoding.UTF8); } }
private void OnDataSent(IAsyncResult asyn) { try { SocketWrapper s = asyn.AsyncState as SocketWrapper; if (s == null) { return; } int bytesSent = s.Socket.EndSend(asyn); SocketLogMgt.SetLog(s.ID + "Sent succeeded. " + bytesSent.ToString() + " bytes."); _allDone.Set(); } catch (Exception err) { SocketLogMgt.SetLastError(this, err); } }
private void CloseWorker() { try { SocketLogMgt.SetLog(this, ": Closing connection.."); _socket.Shutdown(SocketShutdown.Both); _socket.Close(); } catch (Exception err) { SocketLogMgt.SetLastError(err); } finally { _server.RemoveWorker(this); SocketLogMgt.SetLog(this, ": Client Disconnected from: " + _remoteEndPointInfo); SocketLogMgt.SetLog(this, "=============================================\r\n"); } }
private void Disconnect() { if (_socket != null) { try { SocketLogMgt.SetLog(this, _socketID + "Closing connection..."); _socket.Shutdown(SocketShutdown.Both); _socket.Close(); _socket = null; SocketLogMgt.SetLog(this, _socketID + "Connection closed."); SocketLogMgt.SetLog(this, "============================="); } catch (Exception err) { SocketLogMgt.SetLastError(this, err); } } }
private Socket Connect(SocketClientConfig config) { if (_socket != null && _socket.Connected) { return(_socket); } Disconnect(); try { SocketLogMgt.SetLog(this, "============================="); SocketLogMgt.SetLog(this, "Opening connection..."); SocketLogMgt.SetLog(this, config); _socketID = string.Format("({0}) ", SocketHelper.GetNewSocketID()); IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(config.IPAddress), config.Port); _socket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp); _socket.ReceiveTimeout = config.ReceiveTimeout; _socket.SendTimeout = config.SendTimeout; _socket.Connect(ipe); if (_socket.Connected) { SocketLogMgt.SetLog(this, _socketID + "Connection opened."); return(_socket); } else { SocketLogMgt.SetLog(SocketLogType.Error, this, _socketID + "Connection failed."); return(null); } } catch (Exception err) { SocketLogMgt.SetLastError(this, err); return(null); } }
private void OnDataSent(IAsyncResult asyn) { try { int bytesSent = _socket.EndSend(asyn); SocketLogMgt.SetLog(this, _strSocketID + "Sent succeeded. " + bytesSent.ToString() + " bytes."); UpdateActiveDT(); } catch (Exception e) { SocketLogMgt.SetLastError(e); // if communication is ok, but process message failed, do not need to close connection. } finally { CloseWorker(); // close socket only when send data finished // however if you cose the socket after receive data processing finished // (which means the async sending is began), it seams the data can also be succussfully sent, // but in this case, we cannot access the socket object after send data finished. } }
public static IServer Create(string ip, int port) { if (ip == null || ip.Length < 1 || ip == "127.0.0.1") { return(Create(port)); } try { SocketServerConfig cfg = new SocketServerConfig(); cfg.IPAddress = ip; cfg.Port = port; Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); SocketKeepAliveHelper.SetKeepAliveValues(cfg, listener, cfg); listener.Bind(new IPEndPoint(IPAddress.Parse(ip), port)); return(new SocketServer(listener, cfg)); } catch (Exception err) { SocketLogMgt.SetLastError(err); return(null); } }
private void OnDataReceived(IAsyncResult asyn) { try { if (_isClosed) { SocketLogMgt.SetLog(SocketLogType.Warning, this, "Data received, but the socket is closed."); return; } int bytesRead = _socket.EndReceive(asyn); ////------------Handle Multi-byte Charactor------------- ////Buffer all the bytes received and then decode this bytes at one time. ////in order to support multi byte charactor set (for example: utf-8) ////However, ASCII or GB or BIG5 or Unicode are easy, ////we can decode even bytes at each time. //List<BufferWrapper> bufferList = new List<BufferWrapper>(); ////---------------------------------------------------- do { bytesRead = _socket.Receive(_buffer); SocketLogMgt.SetLog(this, _strSocketID + "Receive succeeded. " + bytesRead.ToString() + " bytes."); UpdateActiveDT(); ////------------Handle Multi-byte Charactor------------- //bufferList.Add(BufferWrapper.Create(_buffer, bytesRead)); ////foreach (BufferWrapper w in bufferList) SocketLogMgt.SetLog(">>>>>>>>>>>> " + w.Buffer.Length.ToString()); ////---------------------------------------------------- if (bytesRead > 0) { ////No matter how to cut the buffer, ASCII charactor can always be decoded properly, ////therefore we can use this segment to detect whether an ASCII charactor ending sign (for example "</XMLRequestMessage>") is received. ////See class XmlTest.FormCoding for unit test. string str = _server.Encoder.GetString(_buffer, 0, bytesRead); if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, _strSocketID + ": Data received."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, str); SocketLogMgt.SetLog(this, "------------------------"); } string receiveData = str; if (!string.IsNullOrEmpty(receiveData)) { string sendData = null; ////------------Handle Multi-byte Charactor------------- //receiveData = BufferWrapper.GetString(_server.Encoder, bufferList); //bufferList.Clear(); ////---------------------------------------------------- receiveData = SocketHelper.TrimMessageBlock(receiveData); _server.NotifyRequest(receiveData, ref sendData); ResponseData(sendData); //// if allow multiple session per connection, then continue receiving till connection is closed by the client. //if (_server.Config.AllowMultipleSessionPerConnection) // continue; //else // break; continue; } } }while (bytesRead > 0); // if(bytesRead==0) which means the connection is closed by the client, we will close the worker socket. SocketLogMgt.SetLog(this, "Stop receiving data because the connection is closed by the client."); CloseWorker(); } catch (SocketException err) { //needToContinue = false; SocketLogMgt.SetLastError(err); // if client does not send data in some period of time and the connection will be expired // (controled by the lower levels, and this exception occurs when the client send message again after the connection expired) // or other network exception when receiving data, then close the server socket. CloseWorker(); } catch (Exception e) { SocketLogMgt.SetLastError(e); // if communication is ok, but process message failed, do not need to close connection. } }
public SocketResult SendData(SocketClientConfig config, string content) { SocketResult result = SocketResult.Empty; try { SocketLogMgt.SetLog(this, "============================================="); SocketLogMgt.SetLog(this, ": Send Data Begin."); SocketLogMgt.SetLog(this, config); //string strSend = SocketHelper.PackMessageBlock(content); string strSend = content; if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, ": Data to be sent."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, strSend); SocketLogMgt.SetLog(this, "------------------------"); } Byte[] bytesSent = null; System.Text.Encoding encoder = SocketHelper.GetEncoder(config); if (encoder != null) { bytesSent = encoder.GetBytes(strSend); } if (bytesSent == null) { SocketLogMgt.SetLog(SocketLogType.Error, this, "Encode data failed."); return(SocketResult.SendFailed); } Byte[] bytesReceived = new Byte[config.ReceiveResponseBufferSizeKB * 1024]; SocketLogMgt.SetLog(this, ": Socket prepared."); SocketLogMgt.SetLog(this, "------------------------"); string strReceived = null; StringBuilder sb = new StringBuilder(); IPEndPoint ipe = new IPEndPoint(IPAddress.Parse(config.IPAddress), config.Port); using (Socket socket = new Socket(ipe.AddressFamily, SocketType.Stream, ProtocolType.Tcp)) { int id = SocketHelper.GetNewSocketID(); string strID = "(" + id.ToString() + ") "; //socket.NoDelay = true; socket.SendTimeout = config.SendTimeout; socket.ReceiveTimeout = config.ReceiveTimeout; SocketLogMgt.SetLog(this, strID + "Socket created."); socket.Connect(ipe); if (socket.Connected) { SocketLogMgt.SetLog(this, strID + "Socket connected."); } else { SocketLogMgt.SetLog(SocketLogType.Warning, this, strID + "Connection failed."); return(SocketResult.Disconnect); } _allDone.Reset(); SocketLogMgt.SetLog(this, strID + "Send data."); socket.BeginSend(bytesSent, 0, bytesSent.Length, 0, new AsyncCallback(OnDataSent), new SocketWrapper(strID, socket)); bool rec = true; while (rec) { if (!socket.Connected) { SocketLogMgt.SetLog(SocketLogType.Warning, this, strID + "Connection closed."); break; } SocketLogMgt.SetLog(this, strID + "Receive data."); int bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0); SocketLogMgt.SetLog(this, strID + "Receive succeeded. " + bytes.ToString() + " bytes."); string str = encoder.GetString(bytesReceived, 0, bytes); sb.Append(str); strReceived = sb.ToString(); //rec = !SocketHelper.FindBlockEnding(strReceived); rec = false; // This socket client assume that there is a completed HL7 message (without MLLP signs) in one Receive(); } _allDone.WaitOne(); // need not to set timeout here, we can depend on socket timeout of the Receive() method. socket.Shutdown(SocketShutdown.Both); socket.Close(); SocketLogMgt.SetLog(this, strID + "Socket disconnected."); } SocketLogMgt.SetLog(this, "------------------------"); if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, ": Data received."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, strReceived); SocketLogMgt.SetLog(this, "------------------------"); } //strReceived = SocketHelper.UnpackMessageBlock(strReceived); strReceived = SocketHelper.TrimMessageBlock(strReceived); result = new SocketResult(SocketResultType.Success, strReceived); } catch (Exception err) { SocketLogMgt.SetLastError(this, err); result = new SocketResult(err); } SocketLogMgt.SetLog(this, ": Send Data End"); SocketLogMgt.SetLog(this, "=============================================\r\n"); return(result); }
private SocketResult Send(SocketClientConfig config, string content) { SocketLogMgt.SetLog(this, "============================================="); SocketLogMgt.SetLog(this, ": Send Data Begin."); try { Socket socket = Connect(config); if (socket == null) { return(SocketResult.Disconnect); // failed to connect to remote server } //string strSend = SocketHelper.PackMessageBlock(content); string strSend = content; if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, ": Data to be sent."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, strSend); SocketLogMgt.SetLog(this, "------------------------"); } Byte[] bytesSent = null; System.Text.Encoding encoder = GetEncoder(); if (encoder != null) { bytesSent = encoder.GetBytes(strSend); } if (bytesSent == null) { SocketLogMgt.SetLog(SocketLogType.Error, this, _socketID + "Encode data failed."); return(SocketResult.SendFailed); // failed to encoding outgoing message } _allDone.Reset(); SocketLogMgt.SetLog(this, _socketID + "Send data."); socket.BeginSend(bytesSent, 0, bytesSent.Length, 0, new AsyncCallback(OnDataSent), null); bool rec = true; string strReceived = null; StringBuilder sb = new StringBuilder(); Byte[] bytesReceived = new Byte[config.ReceiveResponseBufferSizeKB * 1024]; while (rec) { if (!socket.Connected) { SocketLogMgt.SetLog(SocketLogType.Warning, this, _socketID + "Connection closed."); break; } SocketLogMgt.SetLog(this, _socketID + "Receive data."); int bytes = socket.Receive(bytesReceived, bytesReceived.Length, 0); SocketLogMgt.SetLog(this, _socketID + "Receive succeeded. " + bytes.ToString() + " bytes."); string str = encoder.GetString(bytesReceived, 0, bytes); sb.Append(str); strReceived = sb.ToString(); //rec = !SocketHelper.FindBlockEnding(strReceived); rec = false; // This socket client assume that there is a completed HL7 message (without MLLP signs) in one Receive(); } _allDone.WaitOne(); // need not to set timeout here, we can depend on socket timeout of the Receive() method. if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, ": Data received."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, strReceived); SocketLogMgt.SetLog(this, "------------------------"); } //strReceived = SocketHelper.UnpackMessageBlock(strReceived); strReceived = SocketHelper.TrimMessageBlock(strReceived); return(new SocketResult(SocketResultType.Success, strReceived)); // send and receive success } catch (SocketException se) { SocketLogMgt.SetLastError(this, se); SocketResult ret = new SocketResult(se); ret.Type = SocketResultType.Unknown; return(ret); // meet exception during sending or receiving // (for example, it may be caused by the connection has expired [controled by the lower levels] // after some period of time without sending or receving), // and we need to recreate a new connection and try again, // please see SendData() for details. } catch (Exception err) { SocketLogMgt.SetLastError(this, err); return(new SocketResult(err)); } finally { SocketLogMgt.SetLog(this, ": Send Data End"); SocketLogMgt.SetLog(this, "=============================================\r\n"); } }
private void OnDataReceived(IAsyncResult asyn) { try { int bytesRead = _socket.EndReceive(asyn); ////------------Handle Multi-byte Charactor------------- ////Buffer all the bytes received and then decode this bytes at one time. ////in order to support multi byte charactor set (for example: utf-8) ////However, ASCII or GB or BIG5 or Unicode are easy, ////we can decode even bytes at each time. //List<BufferWrapper> bufferList = new List<BufferWrapper>(); ////---------------------------------------------------- do { // This socket worker assume that there is a completed HL7 message (without MLLP signs) in one Receive(); bytesRead = _socket.Receive(_buffer); SocketLogMgt.SetLog(this, _strSocketID + "Receive succeeded. " + bytesRead.ToString() + " bytes."); UpdateActiveDT(); ////------------Handle Multi-byte Charactor------------- //bufferList.Add(BufferWrapper.Create(_buffer, bytesRead)); ////foreach (BufferWrapper w in bufferList) SocketLogMgt.SetLog(">>>>>>>>>>>> " + w.Buffer.Length.ToString()); ////---------------------------------------------------- if (bytesRead > 0) { ////No matter how to cut the buffer, ASCII charactor can always be decoded properly, ////therefore we can use this segment to detect whether an ASCII charactor ending sign (for example "</XMLRequestMessage>") is received. ////See class XmlTest.FormCoding for unit test. string str = _server.Encoder.GetString(_buffer, 0, bytesRead); if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, _strSocketID + ": Data received."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, str); SocketLogMgt.SetLog(this, "------------------------"); } string receiveData = str; if (!string.IsNullOrEmpty(receiveData)) { string sendData = null; ////------------Handle Multi-byte Charactor------------- //receiveData = BufferWrapper.GetString(_server.Encoder, bufferList); //bufferList.Clear(); ////---------------------------------------------------- receiveData = SocketHelper.TrimMessageBlock(receiveData); _server.NotifyRequest(receiveData, ref sendData); ResponseData(sendData); break; } } }while (bytesRead > 0); } catch (Exception e) { SocketLogMgt.SetLastError(e); // if communication is ok, but process message failed, do not need to close connection. } }
private void OnDataReceived(IAsyncResult asyn) { try { if (_isClosed) { SocketLogMgt.SetLog(SocketLogType.Warning, this, _strSocketID + ": Data received, but the socket is closed."); return; } int bytesRead = _socket.EndReceive(asyn); //------------Handle Multi-byte Charactor------------- //Buffer all the bytes received and then decode this bytes at one time. //in order to support multi byte charactor set (for example: utf-8) //However, ASCII or GB or BIG5 or Unicode are easy, //we can decode even bytes at each time. List <BufferWrapper> bufferList = new List <BufferWrapper>(); int startIndex = 0, endIndex = 0; //---------------------------------------------------- do { bytesRead = _socket.Receive(_buffer); SocketLogMgt.SetLog(this, _strSocketID + ": Receive succeeded. " + bytesRead.ToString() + " bytes."); UpdateActiveDT(); if (bytesRead > 0) { //------------Handle Multi-byte Charactor------------- bufferList.Add(BufferWrapper.Create(_buffer, bytesRead)); //foreach (BufferWrapper w in bufferList) SocketLogMgt.SetLog(">>>>>>>>>>>> " + w.Buffer.Length.ToString()); //---------------------------------------------------- ////No matter how to cut the buffer, ASCII charactor can always be decoded properly, ////therefore we can use this segment to detect whether an ASCII charactor ending sign (for example "</XMLRequestMessage>") is received. ////See class XmlTest.FormCoding for unit test. string str = _server.Encoder.GetString(_buffer, 0, bytesRead); _sb.Append(str); if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, _strSocketID + ": Data received."); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, str); SocketLogMgt.SetLog(this, "------------------------"); } string receiveData = _sb.ToString(); if (!SocketHelper.FindBlockEnding(receiveData)) { continue; } //------------Handle Multi-byte Charactor------------- receiveData = BufferWrapper.GetString(_server.Encoder, bufferList); //---------------------------------------------------- while (0 <= startIndex && startIndex < receiveData.Length) { endIndex = receiveData.IndexOf(SocketHelper.BlockEndSign, startIndex); if (endIndex < 0) { continue; } string sendMsg = null; string receiveMsg = SocketHelper.UnpackMessageBlock(receiveData, startIndex); if (SocketLogMgt.DumpData) { SocketLogMgt.SetLog(this, _strSocketID + ": Begin processing message:"); SocketLogMgt.SetLog(this, "------------------------"); SocketLogMgt.SetLog(this, receiveMsg); SocketLogMgt.SetLog(this, "------------------------"); } _server.NotifyRequest(receiveMsg, ref sendMsg); ResponseData(sendMsg); startIndex = endIndex + SocketHelper.BlockEndSign.Length; } } }while (bytesRead > 0); SocketLogMgt.SetLog(this, _strSocketID + ": Receiving 0 byte, do nothing and wait till exception or garbage collection to close the socket."); //// if(bytesRead==0) which means the connection is closed by the client, we will close the worker socket. //SocketLogMgt.SetLog(this, "Stop receiving data because the connection is closed by the client."); //CloseWorker(); } catch (SocketException err) { //needToContinue = false; SocketLogMgt.SetLastError(err); // if client does not send data in some period of time and the connection will be expired // (controled by the lower levels, and this exception occurs when the client send message again after the connection expired) // or other network exception when receiving data, then close the server socket. CloseWorker(); } catch (Exception e) { SocketLogMgt.SetLastError(e); // if communication is ok, but process message failed, do not need to close connection. } }