簡體   English   中英

如何使Indy服務器和客戶端在C ++中的單獨線程上偵聽數據而不是在Delphi中

[英]How to make indy server and client listen for data on separate thread in c++ not Delphi

我正在使用C ++ Builder XE8,而且我只是一個初學者。 我對Delphi一無所知。 為了偵聽服務器和客戶端上的傳入數據,我從Flie->New->Other->C++ builder Files插入了Thread Object (在線程視頻演示中看到),並將其命名為TSocketThreard。

在客戶端,我將客戶端套接字分配給TIdIOHandlerSocket var(fsock),並使用以下代碼連續偵聽即將到來的數據。 len是int,s是String var,lbox是TListBox。

void __fastcall TSocketThread::Execute()
{
    FreeOnTerminate = True;
    while(1){
        if (Form1->fsock != NULL && Form1->fsock->Connected()) {
            if(Form1->fsock->CheckForDataOnSource(10))
                Form1->len = Form1->fsock->ReadLongInt();
                Form1->s = Form1->fsock->ReadString(Form1->len);
                Form1->lbox->Items->Add(Form1->s);
        }

    }
}

我試圖從客戶端的onConnect事件和按鈕(也用於將客戶端連接到服務器)啟動它。 但是兩次都凍結了。

在服務器端,我嘗試以相同的方式執行OnExecute事件。 我的意思是,首先將套接字分配給var,將上面的代碼放在線程的(我像以前插入的那樣)execute方法上,然后從onExecute事件啟動線程的start()方法。對於服務器,我想使其工作在異步模式下(至少處理數百個客戶端)。

我可以感覺到我做錯了方法,但是在c ++中很難找到一個很好的例子。 請有人告訴我正確的方法。

Indy服務器已經是多線程的,您無需創建自己的讀取線程。 TIdTCPServer::OnExecute事件在線程中運行,並且每個客戶端都有自己的線程。 只需使用事件提供的套接字,不要使用您自己的變量。

void __fastcall TMyServerForm::IdTCPServer1Execute(TIdContext *AContext)
{
    // use AContext->Connection->IOHandler as needed...
}

在客戶端,您的讀取線程正在執行非線程安全的操作,這可能導致UI凍結以及其他問題。 嘗試類似這樣的方法:

class TSocketThread : public TThread
{
private:
    TIdIOHandler *fIOHandler;
    String fString;
    void __fastcall UpdateListBox();
protected:
    virtual void __fastcall Execute();
public
    __fastcall TSocketThread(TIdIOHandler *AIOHandler);
};

__fastcall TSocketThread::TSocketThread(TIdIOHandler *AIOHandler)
    : TThread(false), fIOHandler(AIOHandler)
{
}

void __fastcall TSocketThread::Execute()
{
    while (!Terminated)
    {
        int len = fIOHandler->ReadLongInt();
        fString = fIOHandler->ReadString(len);
        Synchronize(&UpdateListBox);
    }
}

void __fastcall TSocketThread::UpdateListBox()
{
    Form1->lbox->Items->Add(fString);
}

TSocketThread *Thread = NULL;

void __fastcall TMyClientForm::IdTCPClient1Connected(TObject *Sender)
{
    Thread = new TSocketThread(IdTCPClient1->IOHandler);
}

void __fastcall TMyClientForm::IdTCPClient1Disconnected(TObject *Sender)
{
    if (!Thread) return;
    Thread->Terminate();
    if (!IsCurrentThread(Thread))
    {
        Thread->WaitFor();
        delete Thread;
        Thread = NULL;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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