/ Forside / Teknologi / Udvikling / Delphi/Pascal / Nyhedsindlæg
Login
Glemt dit kodeord?
Brugernavn

Kodeord


Reklame
Top 10 brugere
Delphi/Pascal
#NavnPoint
oldwiking 603
jrossing 525
rpje 520
EXTERMINA.. 500
gandalf 460
gubi 270
DJ_Puden 250
PARKENSS 230
technet 210
10  jdjespers.. 200
TCP forbindelse
Fra : Harald


Dato : 07-01-04 18:55

Hej

Jeg skal have en TCP forbindelse mellem 2 computere men jeg mangler lige
lidt forståelse for hvordan det skal hænge sammen mht. en tråd, dette er
hvad jeg har tænkt mig:
Computer A lytter på en port med en TCP server, ingen problemer her.
Computer B opretter en tråd med en TCP klient som er en Blocking socket, nu
skal computer B så bare vente på beskeder fra computer A, MEN skal også
kunne sende en besked til A hvis tråden får besked fra main programmet om
dette.

Så spørgsmålet er hvordan man i tråden laver det sådan at der hele tiden kan
modtages besked samtidig med at der også kan sendes en besked? Det er vel
ikke meningen at man skal oprette 2 TCP forbindelser, en til at sende på og
en til at modtage på?

Hvad nu hvis A og B sender en besked til hinnanden på samme tid, går der så
kage i det?

Jeg bruger Delphi 7 og windows 2k/XP

Mvh
HK



 
 
Nicolai Hansen (08-01-2004)
Kommentar
Fra : Nicolai Hansen


Dato : 08-01-04 08:26

> Så spørgsmålet er hvordan man i tråden laver det sådan at der hele tiden kan
> modtages besked samtidig med at der også kan sendes en besked? Det er vel
> ikke meningen at man skal oprette 2 TCP forbindelser, en til at sende på og
> en til at modtage på?
>
> Hvad nu hvis A og B sender en besked til hinnanden på samme tid, går der så
> kage i det?

Jeg kan ikke se hvordan det skulle give problemer. TCP protokollen
sikrer at data når frem (eller der meldes fejl til afsenderen). Hvis
du bruger blocking sockets skal du selv finde ud af at læse fra din
forbindelse, så du vil altid kunne færdiggøre din skrivning før du
læser.

Harald (08-01-2004)
Kommentar
Fra : Harald


Dato : 08-01-04 20:35

"Nicolai Hansen" <nic@aub.dk> skrev i en meddelelse
news:d96764ff.0401072326.19044c46@posting.google.com...
> > Så spørgsmålet er hvordan man i tråden laver det sådan at der hele tiden
kan
> > modtages besked samtidig med at der også kan sendes en besked? Det er
vel
> > ikke meningen at man skal oprette 2 TCP forbindelser, en til at sende på
og
> > en til at modtage på?
> >
> > Hvad nu hvis A og B sender en besked til hinnanden på samme tid, går der

> > kage i det?
>
> Jeg kan ikke se hvordan det skulle give problemer. TCP protokollen
> sikrer at data når frem (eller der meldes fejl til afsenderen). Hvis
> du bruger blocking sockets skal du selv finde ud af at læse fra din
> forbindelse, så du vil altid kunne færdiggøre din skrivning før du
> læser.

Så det burde altså virke hvis man laver noget i denne stil:

var
ClientSocket: TClientSocket;
..
..

procedure Thread.Execute;
begin
repeat
if ErDerData then
begin
ClientSocket > HentData
Synchronize(SendDataTilMain);
end;
if SkalDerSendes then
begin
ClientSocket > SendData;
end;
until Terminated;
end;

Data bliver altså gemt af windows indtil programmet er klar til at hente
det, man kan ikke miste data der i teorien kunne komme lige mens programmet
er ved at sende data?
Jeg vil bruge TWinSocketStream til at skrive og læse data hvis ikke andre
har bedre forslag?

Endnu et ?, må man sende data midt i at man også modtager data f.eks.: Der
skal modtages 10k og med TWinSocketStream modtages disse data i klumper af
1k, må man så efter den første 1k er modtaget sende en sjat data og så
fortsætte med at modtage de sidste 9k?

Mvh
HK



Nicolai Hansen (09-01-2004)
Kommentar
Fra : Nicolai Hansen


Dato : 09-01-04 10:25

> var
> ClientSocket: TClientSocket;

Mener at huske at du skal bruge en TCustomWinSocket. Det ka godt være
begge dele virker.

> procedure Thread.Execute;
> begin
> repeat
> if ErDerData then
> begin
> ClientSocket > HentData
> Synchronize(SendDataTilMain);
> end;
> if SkalDerSendes then
> begin
> ClientSocket > SendData;
> end;
> until Terminated;
> end;

Ja - men hvis du vil synkronisere det bedre, vil jeg foreslå en
tilstands maskine. Noget i retning af

repeat
case SocketStatus of
ssOpenConnection:
begin
"opret forbindelse"
end;
ssSendData:
begin
"send"
end;
ssReadData:
begin
"læs"
end;
ssDataToMain:
begin
"synkroniseret aflevering af data til main"
end;
end;
"opdater SocketStatus"
until Terminated;

men det kommer lidt an på hvad det nøjagtigt er du vil.

> Data bliver altså gemt af windows indtil programmet er klar til at hente
> det, man kan ikke miste data der i teorien kunne komme lige mens programmet
> er ved at sende data?

Korrekt. De data du får læses gennem Windows.

> Jeg vil bruge TWinSocketStream til at skrive og læse data hvis ikke andre
> har bedre forslag?

streaming er det anbefalede til blocking sockets.

> Endnu et ?, må man sende data midt i at man også modtager data f.eks.: Der
> skal modtages 10k og med TWinSocketStream modtages disse data i klumper af
> 1k, må man så efter den første 1k er modtaget sende en sjat data og så
> fortsætte med at modtage de sidste 9k?

Ja - intet problem. Med mindre du selv får programmeret problemet ;)
Dette vil dog være umuligt med den foreslåede tilstandsmaskine (så
hvis det er dette du vil skal du bruge din egen metode).

Dog er det ret vigtigt at du laver dine data overførsler på en måde så
du kan se når alle data er overført. Du kan ikke regne med at "alle
data ligger i bufferen når jeg læser" - data vil ankomme i pakker
(sikkert af størrelsen 1024 bytes) og du kan sagtens læse fra bufferen
når 13 ud af 22 pakker er modtaget - mit forslag vil være enten en
specificeret terminator (#0 hvis der overføres tekst, f.eks.), eller
at sende størrelsen på data som de første 2-4 bytes af det sendte.
^^ Dette er generelt det sværeste at få til at spille.

Harald (10-01-2004)
Kommentar
Fra : Harald


Dato : 10-01-04 13:31

"Nicolai Hansen" <nic@aub.dk> skrev i en meddelelse
news:d96764ff.0401090125.4e929e53@posting.google.com...
> > var
> > ClientSocket: TClientSocket;
>
> Mener at huske at du skal bruge en TCustomWinSocket. Det ka godt være
> begge dele virker.
>
> > procedure Thread.Execute;
> > begin
> > repeat
> > if ErDerData then
> > begin
> > ClientSocket > HentData
> > Synchronize(SendDataTilMain);
> > end;
> > if SkalDerSendes then
> > begin
> > ClientSocket > SendData;
> > end;
> > until Terminated;
> > end;
>
> Ja - men hvis du vil synkronisere det bedre, vil jeg foreslå en
> tilstands maskine. Noget i retning af
>
> repeat
> case SocketStatus of
> ssOpenConnection:
> begin
> "opret forbindelse"
> end;
> ssSendData:
> begin
> "send"
> end;
> ssReadData:
> begin
> "læs"
> end;
> ssDataToMain:
> begin
> "synkroniseret aflevering af data til main"
> end;
> end;
> "opdater SocketStatus"
> until Terminated;
>
> men det kommer lidt an på hvad det nøjagtigt er du vil.
>
> > Data bliver altså gemt af windows indtil programmet er klar til at hente
> > det, man kan ikke miste data der i teorien kunne komme lige mens
programmet
> > er ved at sende data?
>
> Korrekt. De data du får læses gennem Windows.
>
> > Jeg vil bruge TWinSocketStream til at skrive og læse data hvis ikke
andre
> > har bedre forslag?
>
> streaming er det anbefalede til blocking sockets.
>
> > Endnu et ?, må man sende data midt i at man også modtager data f.eks.:
Der
> > skal modtages 10k og med TWinSocketStream modtages disse data i klumper
af
> > 1k, må man så efter den første 1k er modtaget sende en sjat data og så
> > fortsætte med at modtage de sidste 9k?
>
> Ja - intet problem. Med mindre du selv får programmeret problemet ;)
> Dette vil dog være umuligt med den foreslåede tilstandsmaskine (så
> hvis det er dette du vil skal du bruge din egen metode).
>
> Dog er det ret vigtigt at du laver dine data overførsler på en måde så
> du kan se når alle data er overført. Du kan ikke regne med at "alle
> data ligger i bufferen når jeg læser" - data vil ankomme i pakker
> (sikkert af størrelsen 1024 bytes) og du kan sagtens læse fra bufferen
> når 13 ud af 22 pakker er modtaget - mit forslag vil være enten en
> specificeret terminator (#0 hvis der overføres tekst, f.eks.), eller
> at sende størrelsen på data som de første 2-4 bytes af det sendte.
> ^^ Dette er generelt det sværeste at få til at spille.

Men hvis det man sender kun er korte tekst strenge på max 200 byte så kan
man vel være 100% sikker på at det hele er modtaget i samme pakke?
Nu vil jeg gå i gang og så lave nogle volsomme test der sender/modtager
nogle 1000 gange mere end der nogenside vil blive tale om, så burde jeg vel
være rimelig sikker på at der vil køre i normal drift.

Mvh
HK



Nicolai Hansen (12-01-2004)
Kommentar
Fra : Nicolai Hansen


Dato : 12-01-04 11:06

> Men hvis det man sender kun er korte tekst strenge på max 200 byte så kan
> man vel være 100% sikker på at det hele er modtaget i samme pakke?

uha - NEJ !!!
hvis du sender en streng på 200 byte kan den godt ligge og "vente lidt
på næste streng" og derefter sende dem i samme pakke.

den ene side sender:
Socket.SendText('hej');
Socket.SendText('med dig');

den anden side modtager:
'hejmed dig'

når du roder med det vil du blvie overrasket over hvor lidt kontrol du
har over de pakker som sendes/modtages. Hav ALTID en terminator på det
du sender så modtageren kan skilde det ad igen.

> Nu vil jeg gå i gang og så lave nogle volsomme test der sender/modtager
> nogle 1000 gange mere end der nogenside vil blive tale om, så burde jeg vel
> være rimelig sikker på at der vil køre i normal drift.

God fornøjelse. Husk din buffer og dine terminators ;) Ellers spår jeg
at det går i ged - og threads er svære at debugge.

Harald (12-01-2004)
Kommentar
Fra : Harald


Dato : 12-01-04 12:18

"Nicolai Hansen" <nic@aub.dk> skrev i en meddelelse
news:d96764ff.0401120205.6ad2f56a@posting.google.com...
> > Men hvis det man sender kun er korte tekst strenge på max 200 byte så
kan
> > man vel være 100% sikker på at det hele er modtaget i samme pakke?
>
> uha - NEJ !!!
> hvis du sender en streng på 200 byte kan den godt ligge og "vente lidt
> på næste streng" og derefter sende dem i samme pakke.
>
> den ene side sender:
> Socket.SendText('hej');
> Socket.SendText('med dig');
>
> den anden side modtager:
> 'hejmed dig'
>
> når du roder med det vil du blvie overrasket over hvor lidt kontrol du
> har over de pakker som sendes/modtages. Hav ALTID en terminator på det
> du sender så modtageren kan skilde det ad igen.
>
> > Nu vil jeg gå i gang og så lave nogle volsomme test der sender/modtager
> > nogle 1000 gange mere end der nogenside vil blive tale om, så burde jeg
vel
> > være rimelig sikker på at der vil køre i normal drift.
>
> God fornøjelse. Husk din buffer og dine terminators ;) Ellers spår jeg
> at det går i ged - og threads er svære at debugge.

Jep, der skulle ikke mange test til før jeg fandt ud af at en terminator er
en go idé. Nu har jeg 3 tråde kørende, en TCP, MySQL og en til RS232 og der
ser ud til at køre fint.
I hver tråd har jeg en sleep(50) for at undgå 100% cpu belastning men det
kan vel ikke give problemer?

Jeg bruger PostThreadMessage til at sende beskeder til trådene og det ser ud
til at virke fint, er der noget man skal huske på mht. PostThreadMessage?

Mvh
HK



Nicolai Hansen (13-01-2004)
Kommentar
Fra : Nicolai Hansen


Dato : 13-01-04 09:23

> Jep, der skulle ikke mange test til før jeg fandt ud af at en terminator er
> en go idé. Nu har jeg 3 tråde kørende, en TCP, MySQL og en til RS232 og der
> ser ud til at køre fint.

:)

> I hver tråd har jeg en sleep(50) for at undgå 100% cpu belastning men det
> kan vel ikke give problemer?

Nej. Selv RS232 har en buffer i Windows (jeg går ud fra at du bruger
WinAPI til at snakke serielt, og ikke port kald til COM porten)

> Jeg bruger PostThreadMessage til at sende beskeder til trådene og det ser ud
> til at virke fint, er der noget man skal huske på mht. PostThreadMessage?

Puha, ikke mit største speciale. Hvad jeg ved er at den sender en
besked til tråden. Det burde være 100% thread safe. Det er jo op til
tråden at fortolke beskeden når den har lyst/tid.

Søg
Reklame
Statistik
Spørgsmål : 177558
Tips : 31968
Nyheder : 719565
Indlæg : 6408921
Brugere : 218888

Månedens bedste
Årets bedste
Sidste års bedste