using System; using System.Net; using System.Net.Sockets; using System.Text; using System.Threading.Tasks; namespace tcpAddResponseProxy { class tcpAddResponseProxy { static void Main(string[] args) { // 待ち受けアドレス、ポート string localEndpointStr = args[0]; string localEndpointPortStr = args[1]; // リダイレクト先アドレス、ポート string remoteEndpointStr = args[2]; string remoteEndpointPortStr = args[3]; IPEndPoint localEndpoint = new IPEndPoint(IPAddress.Parse(localEndpointStr), int.Parse(localEndpointPortStr)); IPEndPoint remoteEndpoint = new IPEndPoint(IPAddress.Parse(remoteEndpointStr), int.Parse(remoteEndpointPortStr)); proxyServer proxy = new proxyServer(localEndpoint, remoteEndpoint); Task task = Task.Run(() => proxy.Listen()); task.Wait(); proxy.Close(); } } class proxyClient { IPEndPoint remoteEndpoint; public proxyClient(IPEndPoint endpoint) { remoteEndpoint = endpoint; } public void Send(string data) { using (TcpClient client = new TcpClient()) { client.Connect(remoteEndpoint); Console.WriteLine("{0} {1} Connect to {2}", DateTime.Now, client.GetHashCode(), client.Client.RemoteEndPoint); using (NetworkStream stream = client.GetStream()) { byte[] buff = Encoding.UTF8.GetBytes(data); stream.Write(buff, 0, buff.Length); Console.WriteLine("{0} {1} Send Data:{2}", DateTime.Now, client.GetHashCode(), data); } } } } class proxyServer { TcpListener listener; IPEndPoint remoteEP; public proxyServer(IPEndPoint localEndpoint, IPEndPoint remoteEndpoint) { listener = new TcpListener(localEndpoint); remoteEP = remoteEndpoint; } public void Close() { listener.Stop(); Console.WriteLine("{0} Stop Listen", DateTime.Now); } public async Task Listen() { listener.Start(); Console.WriteLine("{0} Start Listen", DateTime.Now); while (true) { TcpClient connectClient = await listener.AcceptTcpClientAsync(); Console.WriteLine("{0} {1} Connect from {2}", DateTime.Now, connectClient.Client.GetHashCode(), connectClient.Client.RemoteEndPoint); Task task = Task.Run(() => { ProcessingData(connectClient); connectClient.Close(); }); } } private void ProcessingData(TcpClient connectClient) { byte[] buff = new byte[4096]; // データは4096バイトまで StringBuilder sb = new StringBuilder(); sb.Clear(); using (connectClient) { using (NetworkStream stream = connectClient.GetStream()) { // Node-REDからのリクエストを読み出す int buffIndex = 0; int data; while (buff.Length > buffIndex) { data = stream.ReadByte(); if ((-1 == data) || ('\n' == data) || ('\r' == data)) break; buff[buffIndex] = Convert.ToByte(data); buffIndex++; } sb.Append(Encoding.UTF8.GetString(buff, 0, buffIndex)); Console.WriteLine("{0} {1} Received Data:{2}", DateTime.Now, connectClient.Client.GetHashCode(), sb.ToString()); // リクエストデータを本来のサービスへ送る string dummyData; try { proxyClient proClient = new proxyClient(remoteEP); proClient.Send(sb.ToString() + "\n"); dummyData = "{\"status\": \"OK\", \"data\":" + sb.ToString() + "}"; } catch (Exception e) { dummyData = "{\"status\": \"NG\", \"error\":" + e.Message + "}"; } // Node-REDへダミーのレスポンスを返す byte[] sendData = System.Text.Encoding.UTF8.GetBytes(dummyData + "\n"); stream.Write(sendData, 0, sendData.Length); Console.WriteLine("{0} {1} Return Dummy Response:{2}", DateTime.Now, connectClient.Client.GetHashCode(), dummyData); } } } } }