[英]Efficient multiple tcp clients with intervals
I have been writing a command line program in C# that uses multiple tcp clients that all connect to the same server. 我一直在用C#编写一个命令行程序,该程序使用都连接到同一服务器的多个tcp客户端。 Each client resides in it's own thread. 每个客户端都驻留在其自己的线程中。 At the moment I am trying to work out an effective method of spreading say 5 requests a second efficiently between let's say 4 threads. 目前,我正在尝试一种有效的方法,例如在4个线程之间有效地传播5个请求。
My code currently looks like the following but I still end up with requests overlapping each other. 目前,我的代码如下所示,但最终还是导致请求相互重叠。 Does anyone have any idea how to prevent these overlaps effectively? 有谁知道如何有效地防止这些重叠?
// Max connections is 4, interval is 200
// Loop once to give tcp clients chance to connect
var tcpClients = new TcpClient[_maxConnections];
for(int i = 0; i < _maxConnections; i++)
{
tcpClients[i] = new TcpClient();
tcpClients[i].Connect(host, port);
}
// Loop again to setup tasks
for(int i = 0; i < _maxConnections; i++)
{
Task.Factory.StartNew(TcpHandler, tcpClients[i]);
// Sleep so every task starts separate from each other.
Thread.Sleep(_interval);
}
And then the TcpHandler code looks like: 然后,TcpHandler代码如下所示:
public static void TcpHandler(Object o)
{
// active is already declared
while(_active)
{
var tcpClient = (TcpClient) o;
// .. do some send and receive...
Console.WriteLine("Something here..");
Thread.Sleep(_interval * _maxConnections);
}
}
So as you can see I am sleeping to provide sufficient space between each thread executing yet now and then they still overlap. 因此,您可以看到,我正在努力为每个正在执行的线程之间提供足够的空间,然后它们仍然重叠。
How can I make this threads run parallel without any overlap and limit to 5 times a second spread across all 4? 如何使该线程并行运行而没有任何重叠,并限制所有4个线程每秒传播5次?
Or am I going about this all wrong? 还是我要解决所有这些错误?
Presuming each client requires a separate thread, and that only one thread may be communicating with the server at a given time (no overlap), a lock
in the TcpHandler
method should suffice: 假设每个客户端都需要一个单独的线程,并且在给定时间(不重叠),只有一个线程可以与服务器通信,则TcpHandler
方法中的lock
就足够了:
// Max connections is 4, interval is 200
// Loop once to give tcp clients chance to connect
var tcpClients = new TcpClient[_maxConnections];
// dedicated lock object
static readonly object lockObject = new object();
And then in your TcpHandler method 然后在您的TcpHandler方法中
public static void TcpHandler(Object o)
{
// active is already declared
while(_active)
{
//DO NON-SOCKET RELATED STUFF HERE
// ... code ...
//
//DO SOCKET RELATED STUFF HERE
lock(lockObject)
{
var tcpClient = (TcpClient) o;
// .. do some send and receive...
Console.WriteLine("Something here..");
Thread.Sleep(_interval * _maxConnections);
}
}
}
I am not quite sure why you are doing this but I have used System.Timers (actually an array of timers) in windows services and have staggered the start (intervals). 我不太确定为什么要这样做,但是我在Windows服务中使用了System.Timers(实际上是一组定时器),并且错开了开始时间(间隔)。
In the Elapse event maybe you could use a lock(myobject) { } so they don't overlap? 在Elapse事件中,您可以使用lock(myobject){},以使它们不重叠?
Gina 吉娜
I think you are using sleep to manage connection times.. Why not instead setup a "Maximum connection delay" then use BeginConnect
and a Timer
to look after the connection. 我认为您正在使用睡眠来管理连接时间。为什么不改而设置“最大连接延迟”,然后使用BeginConnect
和Timer
来照顾连接。
eg. 例如。
//setup a timer variable
TCPClient connectionOpening;
_connecting = true;
_connected = false;
connectionOpening = tcpClient;
timer.change(5000, Infinite)
tcpClient.BeginConnect(ClientConnectCallback, tcpClient)
void ClientConnectCallback(iasyncresult ar)
{
_timer.change(infinite, infinite);
TCPClient tcp = (TCPClient)ar.AsyncState;
try
{
//if we have timed out because our time will abort the connect
tcp.EndConnect(ar);
_connected = true;
_connecting = false;
//we are now connected... do the rest you want to do.
//get the stream and BeginRead etc.
}
catch (Exception ex) // use the proper exceptions IOException , socketException etc
{
if (!_connecting)
{
//We terminated the connection because our timer ticked.
}
else
{
//some other problem that we weren't expecting
}
}
void TimerTick(object state)
{
_connecting = false;
_connected = false;
connectionOpening.Close();
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.