Sockety (problem) przy wysyłaniu tekstu.

Odpowiedz Nowy wątek
2006-12-13 22:34

Rejestracja: 14 lat temu

Ostatnio: 4 lata temu

0

Witam,

Siedzę już nad tym xxx godzin i nie mogę wyczaić co robie źle.

Program to serwer czatu, wysyłamy do niego wiadomość a on rozsyła ją wszystkim klientom.

Brzmi bardzo prosto, w praktyce też jest proste tyle że nie działa.

Objawy:
Gdy zalogowany jest tylko jeden klient, serwer sprawuje się doskonale.
po dołączeniu drugiego klienta, serwer wysypuje takim komunikatem:

user image

var
List: TStringList;
    k:integer;
    i,ii,iii,iiii:integer;
    idMessage : TIdMessage;
    s,b,wiadomosc:string;
    zmienna3:pchar;
         sprawdzanieloginu,sprawdzaniehasla:integer;
begin
    for ii:=0 to ServerSocket1.Socket.ActiveConnections-1 do begin
        s:=serversocket1.Socket.Connections[ii].ReceiveText;

        if s <> '' then

            List := TStringList.Create;
            try
                zmienna3 := PChar(s);
                ExtractStrings(['~'], [],zmienna3  , List);

for iii:=listbox1.items.count-1 downto 0 do
                         begin

if (list[0]=listbox1.items[iii])and (list[1]=listbox2.items[iii])

    then
    begin

                Memo1.Lines.Add('Użytkownik: '+list[0] + ' IP: ' + Socket.RemoteAddress+'   wysyla wiadomosc:   '+list[2]);
                for i:=0 to ServerSocket1.Socket.ActiveConnections-1 do

                    serversocket1.Socket.Connections[i].SendText('odbierz~'+list[1]+' > ' +list[2]);

            end;
                       end;

            finally
                List.Free;
            end;
        end;
    end;

działanie kodu (on Client write):
Z początku program odbiera dane od podłączonych klientów..

Dzieli odebrany ciąg znaków, według znaku "~" którym oddzielane są komendy.

Sprawdza czy wyslany login i hasło zgadzają sie z tymi zapisanymi w listbox1 oraz listbox2

Dopisuje do memo1 informacje o operacji

otwiera pętlę wysyłania wiadomości do czekających klientów...

Na moje oko, jest wszystko poprawnie, nie wiem czemu nie działa :(

Jeżeli potrzebne będzie więcej informacji to proszę pytać...

Proszę o pomoc


Pozostało 580 znaków

2006-12-14 04:15

Rejestracja: 16 lat temu

Ostatnio: 7 lat temu

0
  1. idź pan w buroki z takim formatowaniem
  2. if (list[0]=listbox1.items[iii])and (list[1]=listbox2.items[iii]) wypadało by sprawdzić czy w ogóle list[1] istnieje (teoretycznie list[0] jest)
  3. odpal serwer z delphi i zobacz gdzie się zatrzyma, ew postaw breakpointa i zobacz na czym się wywali

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-12-14 10:07

Rejestracja: 14 lat temu

Ostatnio: 4 lata temu

0
  1. krytyka, krytyka :( brak konstruktywnego myślenia
  2. list[1] na 100 % jest...
  3. Postawiłem break pointa.

Wywaliło tutaj:

user image


Pozostało 580 znaków

2006-12-14 10:35

Rejestracja: 16 lat temu

Ostatnio: 7 lat temu

0
seba22 napisał(a)
  1. krytyka, krytyka :( brak konstruktywnego myślenia

poświęcił byś 30 sekund na przeformatowanie tego cuda i nie było by krytyki

  1. list[1] na 100 % jest...
  2. Postawiłem break pointa.
    Wywaliło tutaj:

a ja Ci mówię, że na 100% nie ma


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-12-14 10:57

Rejestracja: 14 lat temu

Ostatnio: 4 lata temu

0

Witaj,

  1. Gdybyś dał sugestie, to z przyjemnością i wdzięcznością bym się tym zajął, nie jestem w tym oblatany, ale staram się jak mogę.

Słuchaj, postawiłem showmessage(s); na samym początku zaraz po:
s:=serversocket1.Socket.Connections[ii].ReceiveText;

I okazało się że:

jeżeli jest jeden klient s: zawsze przyjmuje dobre wartości.
jeżeli są 2 klienty s:
w pierwszej turze, przyjmuje dobre wartości xxx~xxx~xxx
w drugiej turze jest puste, i program wysypuje :(

Jak się przed tym zabezpieczyć, i czemu jest puste ? !


Pozostało 580 znaków

2006-12-14 11:36

Rejestracja: 16 lat temu

Ostatnio: 7 lat temu

0
  1. masz cały art o formatowaniu. Głównie chodzi mi o to rozstrzelenie textu, które bardo utrudnia połapanie się

co do pytania to

  1. nie używam TServerSocket (wolę robić po swojemu na wątkach)
  2. to
    for ii:=0 to ServerSocket1.Socket.ActiveConnections-1 do begin
    s:=serversocket1.Socket.Connections[ii].ReceiveText;

jest dla mnie dziwne bo lecisz po WSZYSTKICH połączeniach niezależnie od tego, który klient coś wysłał. W efekcie przy dwóch klientach podłączonych jeśli wyśle coś pierwszy to w pierwszym przebiegu odbierzesz to co wysłał a w drugim nie odbierzesz nic bo drugi nic nie wysłał.
Jak nic nie wysłął to

if s <> '' then
// <- tu by się begin przydał i powinno działać
  List := TStringList.Create; //to się nie wykona
try //ale od tego miejsca już tak niezależnie czy s <> '' czy nie

BTW w jakim zdarzeniu wywołujesz powyższy kod?

ale i tak całe to wywołanie jest dla mnie dziwne - jak będziesz miał 100 klientów podpiętych i jeden coś wyśle to serwer po prostu Ci umrze na jakieś 10 minut bo pozostałe 99 klientów da Ci s = '' ale dopiero po 6 sekundach każdy (taki jest zazwyczaj ReadTimeOut ustawiony


- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

2006-12-14 12:03

Rejestracja: 14 lat temu

Ostatnio: 4 lata temu

0
  1. Przepraszam, myślałem że chodzi Ci o składnie

  2. To jest zdarzenie On Client Read

Założenie jest takie...
Klient powiedzmy umownie 1 wysyła tekst do serwera.

Serwer odbiera ten tekst, i wysyła do wszystkich klientów łącznie ! z tym co wysłał !

I w takiej konwencji chciał bym to utrzymać.

Jeżeli tam gdzie zasugerowałeś wstawiłem begin, to niestety działa tylko jeden klient, drugiego już w ogóle nie bierze.

// Edytowane:

Dziękuję, wstawiłem cały kod odpowiedzialny za wysyłanie danych itp, po :
List := TStringList.Create; //to się nie wykona

:)
Bo jeżeli jest puste, to ma się nie wykonać cała operacja, a nie tylko tworzenie list-a.


Pozostało 580 znaków

2006-12-14 12:17

Rejestracja: 16 lat temu

Ostatnio: 7 lat temu

0

to przecież OnClientRead przekazuje Ci socket, z którego nadeszło połączenie (Socket: TCustomWinSocket) więc po co sprawdzasz wszystkie??

powinno robić to samo co powyższe

var
  List: TStringList;
  i: integer;
  s: string;
begin
  s := Socket.ReceiveText;
  if s <> '' then
  begin
    List := TStringList.Create;
    try
      ExtractStrings(['~'], [], PChar(s), List);
      Memo1.Lines.Add('Użytkownik: ' + list[0] + ' IP: ' + Socket.RemoteAddress + ' wysyla wiadomosc:   ' + list[2]);
      for i := 0 to ServerSocket1.Socket.ActiveConnections - 1 do
        serversocket1.Socket.Connections[i].SendText('odbierz~' + list[1] + ' > ' + list[2]);
    finally
      FreeAndNil(List);
    end;
  end;
end;

- Ciemna druga strona jest.
- Nie marudź Yoda, tylko jedz tego tosta.
Google NIE GRYZIE!
Pomogłem - kliknij

Pozostało 580 znaków

Odpowiedz

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