在C#中使用Socket改进TCP转发器

在C#中使用Socket改进TCP转发器,第1张

概述在C#中使用Socket改进TCP转发器

我已经实现了一个连接到后端服务器的简单的TCP转发器。 该服务器在http://localhost:5000上设置,并且此TCP转发器正在侦听http://localhost:5001 。 使用另一台机器来产生负载使用wrk 这是一个http基准testing工具来发电机负载 ,我有2个不同的结果。 当我将负载直接发送到基于asp.net core web API上时,每天处理超过230K个请求/秒,但是当我向这个TCP转发器发送负载时,可以处理83Krequest /秒。 这里是代码:

using System; using System.Net; using System.Net.sockets; namespace BrunoGarcia.Net { static voID Main(string[] args) { new TcpForwarderSlim().Start( new IPEndPoint(IPAddress.Parse(args[0]),int.Parse(args[1])),new IPEndPoint(IPAddress.Parse(args[2]),int.Parse(args[3]))); } public class TcpForwarderSlim { private Readonly Socket _mainSocket = new Socket(AddressFamily.InterNetwork,SocketType.Stream,ProtocolType.Tcp); public voID Start(IPEndPoint local,IPEndPoint remote) { _mainSocket.Bind(local); _mainSocket.Listen(10); while (true) { var source = _mainSocket.Accept(); var destination = new TcpForwarderSlim(); var state = new State(source,destination._mainSocket); destination.Connect(remote,source); source.BeginReceive(state.Buffer,state.Buffer.Length,OnDataReceive,state); } } private voID Connect(EndPoint remoteEndpoint,Socket destination) { var state = new State(_mainSocket,destination); _mainSocket.Connect(remoteEndpoint); _mainSocket.BeginReceive(state.Buffer,SocketFlags.None,state); } private static voID OnDataReceive(IAsyncResult result) { var state = (State)result.AsyncState; try { var bytesRead = state.sourceSocket.EndReceive(result); if (bytesRead > 0) { state.DestinationSocket.Send(state.Buffer,bytesRead,SocketFlags.None); state.sourceSocket.BeginReceive(state.Buffer,state); } } catch { state.DestinationSocket.Close(); state.sourceSocket.Close(); } } private class State { public Socket SourceSocket { get; private set; } public Socket DestinationSocket { get; private set; } public byte[] Buffer { get; private set; } public State(Socket source,Socket destination) { SourceSocket = source; DestinationSocket = destination; Buffer = new byte[8192]; } } } }

你觉得有什么问题? 当我使用TCP转发器时,如何改进结果?还是有更好的方法让隧道或转发器侦听端口并将TCP请求发送到2个或更多后端服务之一?

从C#中正在增长的文件中读取?

C#.NET从Web应用程序的串行端口访问

进程启动作为域pipe理员从用户启动进程与UAC在域networking中激活

什么会导致进程停止重新创build?

windows *** 作系统体系结构书

直到state.DestinationSocket.Send完成,才开始监听更多的数据。 开始处理发送后,您可以立即开始监听更多的数据,多个BeginSend调用的顺序将被保留,所以如果切换到该位置,您可以在前一个请求完成之前开始处理下一个请求。

重要的提示! 您现在需要为每个新的BeginReceive请求创建一个新缓冲区(或使用一个缓冲区池)。 下面是未经测试的代码,但希望是足够接近,让你在正确的道路上。

public class TcpForwarderSlim { private Readonly Socket _mainSocket = new Socket(AddressFamily.InterNetwork,IPEndPoint remote) { _mainSocket.Bind(local); _mainSocket.Listn(10); while (true) { var source = _mainSocket.Accept(); var destination = new TcpForwarderSlim(); var state = new State(source,state); } private static voID OnDataReceive(IAsyncResult result) { var state = (State)result.AsyncState; try { var bytesRead = state.sourceSocket.EndReceive(result); if (bytesRead > 0) { //Start an asyncronous send. var sendAr = state.DestinationSocket.BeginSend(state.Buffer,null,null); //Get or create a new buffer for the state object. var oldBuffer = state.ReplaceBuffer(); state.sourceSocket.BeginReceive(state.Buffer,state); //Wait for the send to finish. state.DestinationSocket.EndSend(sendAr); //Return byte[] to the pool. state.AddBuffertopool(oldBuffer); } } catch { state.DestinationSocket.Close(); state.sourceSocket.Close(); } } private class State { private Readonly ConcurrentBag<byte[]> _bufferPool = new ConcurrentBag<byte[]>(); private Readonly int _bufferSize; public Socket SourceSocket { get; private set; } public Socket DestinationSocket { get; private set; } public byte[] Buffer { get; private set; } public State(Socket source,Socket destination) { SourceSocket = source; DestinationSocket = destination; _bufferSize = Math.Min(SourceSocket.ReceiveBufferSize,DestinationSocket.SendBufferSize); Buffer = new byte[_bufferSize]; } /// <summary> /// Replaces the buffer in the state object. /// </summary> /// <returns>The prevIoUs buffer.</returns> public byte[] ReplaceBuffer() { byte[] newBuffer; if (!_bufferPool.TryTake(out newBuffer)) { newBuffer = new byte[_bufferSize]; } var oldBuffer = Buffer; Buffer = newBuffer; return oldBuffer; } public voID AddBuffertopool(byte[] buffer) { _bufferPool.Add(buffer); } } }

总结

以上是内存溢出为你收集整理的在C#中使用Socket改进TCP转发器全部内容,希望文章能够帮你解决在C#中使用Socket改进TCP转发器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1283757.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-09
下一篇 2022-06-09

发表评论

登录后才能评论

评论列表(0条)

保存