Problem obsługi polecenia w innym wątku

0

Witam Serdecznie,

Mam problem z obsługą (close) w innym zdarzeniu, niż generowany przez komponent IdTCPServer. Zaznaczam, że jestem początkujący.

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext);

begin
  AContext.Connection.Socket.Close;     //Tutaj działa rozłącza klienta
end;  

Natomiast nie za bardzo wiem jak można rozłączyć klienta w innym zdarzeniu np. poprzez kliknięcie przycisku

procedure TForm1.Button1Click(Sender: TObject);

begin
  TIdContext(0).Connection.Socket.Close;   // tutaj kombinuje jak dostać sie do tego konkretnego wątku
end;  

Wyskakuje mi błąd o naruszeniu nieodpowiedniego obszaru pamięci. Czy wie ktoś może jak mi pomóc w tym problemie?

screen1.jpg

0

Nie moj kod ale znalazlem cos takiego:

with IdTCPServer1.Threads.LockList do
try
for r := 0 to Count - 1 do begin
TIdPeerThread(Items[r]).Connection.DisconnectSocket;
end; 
finally 
IdTCPServer1.Threads.UnlockList; 
end;

To wyrzuca wszystkich Klientow. Wiec moze wystarczy:

with IdTCPServer1.Threads.LockList do
try
TIdPeerThread(0).Connection.DisconnectSocket;
finally 
IdTCPServer1.Threads.UnlockList; 
end;
0

Nie mam w komponecie takiego modułu jak TIdPeerThread. Może w linuxie nazywa się on jakoś inaczej?

0

Moze sprobuj z TIdContext, nie pracowalem nigdy na Indy :)

0

Wpisuje:

TIdContext(0).Connection.Socket.Close;   

I wywala to samo co w załączniku

0

A nie mozesz przy OnConnect (ClientConnect?) wrzucic klienta w tablice np Clnts i potem po prostu dac:

Clnts[0].Disconnect

?

0

Nic to nie daje.

2

Musisz pobrać Context spróbuj coś w ten deseń:

var
  List: TIdContextThreadList;
  Context: TIdContext;
begin
  List:= IdTCPServer1.Contexts;
  List.LockList;
  Context:= TIdContext(TIdContextList(List).Items[0]); //nie wiem czy to jest prawidłowo
  Context.Connection.Socket.Close;
  List.UnlockList;
end;

albo:

var
  List: Tlist;
begin
  List:= IdTCPServer1.Contexts.LockList;
  TIdContext(List.Items[0]).Connection.Socket.Close;
  IdTCPServer1.Contexts.UnlockList;
end;
0

Dziekuje Ci, rozwiązałeś mój problem. Gdybym mógł tylko Ci zapytać do czego służy funkcja LockList ? Bo myślę, że ty będziesz wiedział.
I jeszcze raz dziękuje, że pochyliłeś głowę nad moim problemem z którym od dość długo walczyłem.

2

Odpowiem za kAzka. Chociaż nie znam tych metod i komponentów. Ale stosowałem SimpleTCP pod WinAPI. Tam też są podobne mechanizmy dla serwerów TCP. Chodzi o dostęp do zmiennych w wątkach poprzez sekcje krytyczne. Bo o ile się nie mylę, to gdyby wywyływac te rzeczy bez tego, można by było narobić sobie bałaganu.

W sensie serwer mógłby się zachować w sposób nieprawidłowy i niekontrolowany. Ponieważ było by możłiwe iż inny wątek dostawał by się w identycznym czasie do na przykład listy klientów. I próbował dokonywać na niej operacji łącznie z usuwaniem czy rozłączaniem. Po prostu doszło by do sytuacji gdzie nastepuje niekontrolowany dostęp do tego, czego już na przykład nie ma. Jednak ktoś inny może Tobie jeszcze to dokładniej wytłumaczyć. Poczytaj o sekcjach krytycznych.

Przykładowy wycinek z kodu gdzie używam SimpleTCP i tworzę prosty serwer HTTP. Sam autor zresztą sugeruje taki sposób używania przy pisaniu jakichkolwiek serwerów z użyciem tego modułu.

      SList.Lock;
      for I := 0 to SList.Count - 1 do
      begin
        if SList[I] = TTcpSocket(P) then
        begin
          SList[I].WriteLn(AnswerStr);
          SList[I].Close;
        end;
      end;
      SList.Unlock;
    end;

Ogólnie fajnie, ze wnikasz. Ale czasami nie powinno się też za bardzo wnikać, tylko pewne rzeczy uznać za pewnik i zalecane. Tymbardziej, że skoro sam autor tak podaje w przykładzie zastosowania jego kodu http://piechnat.pl/index.php/files/highlight/tools/simpletcp/Server.dpr

Podsumowując nie jest zalecane i nie powinno się robić tego inaczej. Chyba, że chce się mieć bubel, a nie porządnie działający serwer. Lepiej praktykować rozwiązania dobrze udokumentowane - jesli się da takie zastosować - a o których wiadomo, że zachowają się jak trzeba. I nie sprawią nam więcej problemów niż gdybyśmy mieli je za nic ;)

0

Nie wiem jak to wyrazić po prostu umożliwia bezpieczne operowanie na liście wątków po prostu jest to Lock wchodzi do sekcji krytycznej Unlock opuszcza sekcje krytyczną.

0

Coś mniej więcej kumam. W każdym razie dzięki serdecznie za odpowiedź wszystkim

1 użytkowników online, w tym zalogowanych: 0, gości: 1