2014-10-14 3 views
0

У меня есть переменная X-номера электронного оборудования (метеостанции) в моей локальной сети, каждое устройство обеспечивает подключение ServerSocket к определенному IP-порту и порту, у меня есть приложение, которое подключается ко всем такое оборудование, мое приложение знает IP-адреса и порты этих устройств, поскольку они зарегистрированы в базе данных, чтобы открыть мое приложение, я создаю динамически [TClientSocket (Array)] подключение к каждому из этих устройств, что впоследствии изменяет много информации , как беседа, спросите температуру все оборудование, и они ответят мне, или я могу попросить одну температуру, влажность к другой, скорость ветра к другому и т. д. ... через внутренние операции. Сегодня я делаю цикл FOR, и все связанное с ним оборудование знает, какая операция с оборудованием имеет мое программное обеспечение, а затем совершает случайный разговор с каждым нарядом, но это происходит медленно, так как увеличивает количество устройств, которые замедляют FOR. То, что я делаю, является нитью для удаления FOR, интересно, возможно ли это. OnConnect, OnRead и т. Д. Мои события TClientScojet назначаются при создании массива TClientSocket, поэтому я в конечном итоге ожидаю его, а затем использую другое и не могу удовлетворить все оборудование одновременно. Я бы хотел использовать эту тему для всего оборудования и встретиться в одно и то же время, но не доминирующую над концепцией и использованием, если кто-то знает, как я могу улучшить этот код, я очень благодарен.Приложение, которое подключается к нескольким устройствам в сети

Сегодня я использую этот класс я создал расширенную TClientSocket:

type 
    TTermoCenter = class(TClientSocket) 
    private 
    countSema: Thandle; 
    access: TCriticalSection; 
    ... 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    procedure Push(inObject: TPalavra; priority: Integer); virtual; 
    function Pop(pResObject: pObject; timeout: Integer): Boolean; 
    end; 

Вот конструктор:

constructor TTermoCenter.Create(AOwner: TComponent); 
var 
    I: Integer; 
begin 
    inherited; 
    access := TCriticalSection.Create; 
    ... 
end; 

Вот деструктор:

destructor TTermoCenter.Destroy; 
var 
    I: Integer; 
begin 
    ... 
    access.Free; 
    closeHandle(countSema); 
    inherited; 
end; 

объявление переменной:

var 
    termocenters: array of TTermoCenter; 

При создании моей формы, я определить размер моего массива

SetLength(termocenters, dm.sqlTermocenter.RecordCount); 

И я создаю свои связи на основе того, что в базе данных:

var 
    SocketTmp: TTermoCenter; 

    while not cds.Eof do 
    begin 
    SocketTmp := TTermoCenter.Create(nil); 
    SocketTmp.name := 'cdsNome'; 
    SocketTmp.Port := 'cdsPorta'; 
    SocketTmp.ClientType := ctNonBlocking; 
    SocketTmp.Host := 'cdsIP'; 
    // atribui eventos 
    SocketTmp.OnRead := TCPRead; 
    SocketTmp.OnConnect := TCPConnect; 
    SocketTmp.OnDisconnect := TCPDisconnect; 
    SocketTmp.OnError := TCPError; 

    //Coloca no Array 
    termocenters[I] := SocketTmp; 
    try 
     termocenters[I].Active := True; 
     sleep(1000); 
    except 
     on E: Exception do 
     frmMain.mmErros.Lines.Add(TimeToStr(now) + ' - ' + E.ClassName + ' CriaConexao : ' + E.Message); 
     end; 
     end; 
    end; 
    cds.Next; 
end; 
end; 

Это хорошее резюме код, который у меня есть сегодня, мне нужна помощь в реализации Threads. Спасибо.

+0

Назначение символьной строки 'TClientSocket.Port' не компилируется. Вы уверены, что ваш код вообще компилируется? Также непонятно, почему здесь присутствуют экземпляр «TCriticalSection» и «Сон». –

ответ

2

Использование событий TClientSocket будет работать очень хорошо при условии, что вы создаете объекты TClientSocket в контексте потока, который имеет контур сообщения, такой как основной поток пользовательского интерфейса.

Вы используете неблокирующий режим, поэтому настройка Active=True не будет блокировать ваш цикл. Соединения будут происходить в фоновом режиме. Когда вы получаете событие OnConnect, он сообщает вам конкретный TCustomWinSocket, который подключен, поэтому вы знаете, к какому конкретному устройству вы можете начать отправлять команды. Если вы получаете событие OnError, оно сообщает вам, была ли это ошибка подключения или нет, поэтому вы можете узнать, к каким устройствам вы не можете подключиться.

Когда запускается OnRead, он сообщает вам конкретный TCustomWinSocket, который отправляет данные, поэтому вы знаете, какое устройство сообщает информацию.Поскольку вы используете неблокирующий режим, данные, предоставленные событием OnRead, могут (и обычно будут) неполными, поэтому просто будьте осторожны с ним где-то в стороне (например, используя свойство TCustomWinSocket.Data, чтобы удерживать указатель на буфер, который вы добавлять новые данные) и извлекать только заполненные сообщения из буфера, оставляя неполные сообщения в буфере, которые будут завершены позже. Для каждого полного сообщения вы можете использовать/обновлять информацию для этого конкретного устройства по мере необходимости.

Если у вас возникли проблемы с использованием событий, то, пожалуйста, покажите свой фактический код. То, что вы показали до сих пор, недостаточно для диагностики любых проблем, которые у вас возникают.

+0

Проект с полным исходным кодом https://mega.co.nz/#!BAVBwTAb!fdzyS9ENPMWul3wC8GFkKATiJ7whKB7Xzgo5FUHlD6M –

Смежные вопросы