簡體   English   中英

間隔有效的多個tcp客戶端

[英]Efficient multiple tcp clients with intervals

我一直在用C#編寫一個命令行程序,該程序使用都連接到同一服務器的多個tcp客戶端。 每個客戶端都駐留在其自己的線程中。 目前,我正在嘗試一種有效的方法,例如在4個線程之間有效地傳播5個請求。

目前,我的代碼如下所示,但最終還是導致請求相互重疊。 有誰知道如何有效地防止這些重疊?

// 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);
}

然后,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);
    }
}

因此,您可以看到,我正在努力為每個正在執行的線程之間提供足夠的空間,然后它們仍然重疊。

如何使該線程並行運行而沒有任何重疊,並限制所有4個線程每秒傳播5次?

還是我要解決所有這些錯誤?

假設每個客戶端都需要一個單獨的線程,並且在給定時間(不重疊),只有一個線程可以與服務器通信,則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();

然后在您的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);
        }
    }
}

我不太確定為什么要這樣做,但是我在Windows服務中使用了System.Timers(實際上是一組定時器),並且錯開了開始時間(間隔)。

在Elapse事件中,您可以使用lock(myobject){},以使它們不重疊?

吉娜

我認為您正在使用睡眠來管理連接時間。為什么不改而設置“最大連接延遲”,然后使用BeginConnectTimer來照顧連接。

例如。

//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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM