using System; using System.Net; using System.Net.Sockets; public class TCPPipe { protected class SocketPacket { public System.Net.Sockets.Socket TCPSocket; public byte[] DataBuffer = new byte[1]; } public delegate void OnReceiveLineCallback(string line); public delegate void OnDisconnectedCallback(SocketException se); public event OnReceiveLineCallback OnReceiveLine; public event OnDisconnectedCallback OnDisconnected; protected Socket _TCPSocket; protected IAsyncResult _Result; protected AsyncCallback _Callback; protected string _Buffer = String.Empty; public bool Connected { get { if (_TCPSocket != null && _TCPSocket.Connected) return true; else return false; } } public TCPPipe() { } public SocketException Connect(string address, int port) { if (_TCPSocket != null && _TCPSocket.Connected) Disconnect(); try { IPAddress ip; if (!IPAddress.TryParse(address, out ip)) { IPAddress[] ips = Dns.GetHostAddresses(address); ip = ips[0]; } _TCPSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); IPEndPoint ipEndPoint = new IPEndPoint(ip, port); _TCPSocket.Connect(ipEndPoint); if (_TCPSocket.Connected) { WaitForData(); return null; } else { return new SocketException(10000); } } catch (SocketException se) { return se; } } public void Disconnect() { _TCPSocket.Disconnect(true); } public void SendData(byte[] data) { if (Connected) _TCPSocket.Send(data); else throw new InvalidOperationException("socket is not connected"); } public void SendLine(string message) { if (Connected) { byte[] byData = System.Text.Encoding.ASCII.GetBytes(message + "\n"); _TCPSocket.Send(byData); } else { throw new InvalidOperationException("socket is not connected"); } } void WaitForData() { try { if (_Callback == null) _Callback = new AsyncCallback(OnDataReceived); SocketPacket packet = new SocketPacket(); packet.TCPSocket = _TCPSocket; _Result = _TCPSocket.BeginReceive(packet.DataBuffer, 0, packet.DataBuffer.Length, SocketFlags.None, _Callback, packet); } catch (SocketException se) { Console.WriteLine(se.Message); } } static char[] splitNull = { '\0' }; static string[] splitLines = { "\r", "\n", "\r\n" }; void ReceiveData(string data) { if (OnReceiveLine == null) return; //string[] splitNull = { "\0" }; string[] line = data.Split(splitNull, StringSplitOptions.None); _Buffer += line[0]; //string[] splitLines = { "\r\n", "\r", "\n" }; string[] lines = _Buffer.Split(splitLines, StringSplitOptions.None); if (lines.Length > 1) { int i; for (i = 0; i < lines.Length - 1; i++) { if (lines[i].Trim().Length > 0) OnReceiveLine(lines[i]); } _Buffer = lines[i]; } } void OnDataReceived(IAsyncResult asyn) { try { SocketPacket packet = (SocketPacket)asyn.AsyncState; int end = packet.TCPSocket.EndReceive(asyn); char[] chars = new char[end + 1]; System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder(); int charLen = d.GetChars(packet.DataBuffer, 0, end, chars, 0); System.String data = new System.String(chars); ReceiveData(data); WaitForData(); } catch (ObjectDisposedException) { Console.WriteLine("WARNING: Socket closed unexpectedly"); } catch (SocketException se) { if (!_TCPSocket.Connected) OnDisconnected(se); } } }