BCB6 hjälp med sockets

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: BCB6 hjälp med sockets

Inlägg av Icecap »

Äntligen! Har varit tvungen att göra så himla mycket annat att det har varit svårt att hinna med - men för en kort stund sedan fick jag min första programmeringskontakt med serieportsservrarna.

Känns lite som att ha fått den första LED att blinka...
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: BCB6 hjälp med sockets

Inlägg av sodjan »

Kul! :-)

Beskriv gärna vilken av metoderna du valde.
Sockets eller COM-portar. Trådar eller inte...
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: BCB6 hjälp med sockets

Inlägg av Icecap »

Jag kör enl. ditt råd: en åt gången. Därmed behövs ingen trådar och debug blir satans mycket enklare.

Är det en enhet som är kopplat till en COM-port öppnas denna som en fil ("\\.\COMx"), annars öppnas den som en TCP (xxx.xxx.xxx.xx:pp).

Det sker en sekvensering som ska putsas lite avseende timing osv:
1: Öppna porten - vilken det än är.
2: Verifiera att porten är öppen. Detta för att ge TCP tid att öppna och ge "On_Connect"-signal.
3: Om serienummer på invertern är känd hopp till steg 6.
4: Begär serienummerdata.
5: Vänta på data eller timeout. Kommer det data ska serienumret sparas vidare fram till övervakning - som är en senare fråga.
6: Begär de intressanta data.
7: Vänta på data eller timeout. Kommer det data ska de viktiga extraheras och läggas i minnet.
8: Stäng port - vilken det nu är.
9: Signaler att nästa enhet i listan ska frågas.

Sekvensen styrs av en timer som kallar sekvens-snudden och det verkar fungera bra. Jag har jo ifs. också kör det system många gångar i µC.

Jag har ju - efter råd av TomasL - fått ett antal MOXA NPort 5150 och de fungerar riktigt bra.
Jag har testat att skicka data från programmet till en av dom idag och har sett att Tx hoppa till som den ska.

Imorgon ska jag ta emot data och jag vill till en början bara loopa porten för att få skrivning & läsning att fungera.

Jag ämnar att ha en "skicka denna datablock"-funktion som kolla om det är COM-port eller TCP och skickar den på rätt sätt liksom jag ska ha en "hämta data"-funktion som hämtar från den aktiva anslutningen. På det vis får jag ett transparent system som medger att jag bara ska skicka data och hämta data utan att bekymra mig om var de ska till eller kommer ifrån.

Öppning och stängning av port fungerar bra, skrivningen likaså. Alltså är det "bara" läsningen av port som fattas innan jag kan skjuta skarpt och leka med data som skickas och tas emot.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: BCB6 hjälp med sockets

Inlägg av Icecap »

Nu har jag kommunikationen till att fungera. Kan öppna TCP-socket och får kontakt, kan skicka och hämta data och allt verkar OK just nu.

Men jag har ett problem som jag inte vet hur jag ska lösa:
Om jag rycker ut TP-ledningen från LAN till Serieportsservern kommer det såklart ett felmeddelande om att det inte går att få kontakt. Helt enligt planerna.

Jag har en On_Error-event som skriver ut ATT det blir skit. Efter ett tag kommer det en informations-ruta upp med felkod 10060 (Connection timed out).

Sedan poppar det ytterligare ruter (många med tiden) upp med felkod 10061 (Connection refused).

Dessa ruter är väl systemmeddelanden men jag skulle mycket gärna fånga dessa fel och bara skriva dom i loggen och därmed inte fylla skärmen med skiten.

De fortsätter ju att komma även efter att jag återansluter kabeln och det är först en omstart av programmet som tar bort det.

Finns det ett sätt att "nolla" dom efter att jag har accepterat det hela?

EDIT: Tror att det är löst nu!

Eventen för fel är:
void __fastcall TForm1::ClientSocket1Error(TObject *Sender, TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode)

När jag har kört det som ska köras testade jag att sätta ErrorCode till 0 - och rutorna slutade komma upp!

Men när jag återigen kopplar in nätverket på serieportsservern får jag fortfarande Connection Refused 10061). Alltså fylls skärmen inte med skit men jag skulle gärna vilja kunde återställa Clienten så att kommunikationen kan återupptas automatisk.

Letade lite och hittade en text:
"When a connection between sockets is broken, the sockets should be discarded and recreated. When a problem develops on a connected socket, the application must discard and recreate the needed sockets in order to return to a stable point."

Och jag är okunnig i hur jag kan göra detta...
Senast redigerad av Icecap 10 maj 2017, 15:30:26, redigerad totalt 1 gång.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: BCB6 hjälp med sockets

Inlägg av sodjan »

Får du "10061 (Connection refused)" även om kabeln *inte* är ansluten?
Eller är det enbart efter att du har anslutit kabeln igen?

Dessa servers brukar enbart acceptera 1 aktiv uppkoppling på varje port.
Sannolikt upplever servern att den fortfarande har en aktiv uppkoppling,
och det vanliga svaret är något i stil med "Connection Refused". Men då
borde du inte få det om kabeln fortfarande är "ur"...
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: BCB6 hjälp med sockets

Inlägg av Icecap »

Första fel jag får är 10061 (Connection refused), sedan är det 10060 (Connection timed out).

Men nu har jag hittat något - som dock fortfarande är dumt mot mig :sick:

Jag har nu ändrat mitt sätt att göra det på till att faktisk kalla Socket->Close() och Socket->Open().

Men nu är det problemet att jag får 10049 (Cannot assign requested address)...

Men NU tror jag att jag är nära målet!
Jag testade att BARA kalla Socket->Open() med de parameter som behövs och det ser ut att fungera.

Innan gjorde jag slarvigt nog så att jag fibblade med de "vanliga" parameter (ClientSocket1->Address = "en sträng"; ->Port = 4001; osv) men nu kör jag ENBART ->Open("", "192.168.1.240", "", 4001, ctNonBlocking);

Det fungerar bra när jag kör normalt och såklart får jag lite fel när jag drar ut kabeln.

Jag hade en connection-timeout på 500ms och fick sedan 10061 (Connection refused) men nu ändrade jag timeout till 3000ms och nu verkar det fungera utan problem.

Drar jag ut sladden blir det såklart fel, sätter jag den tillbaka går det en aning trögt en gång, sedan kör det.

EDIT: Jag kör Borland C Builder 6 och har på formen en TClientSocket.
För att få det till att fungera måste jag börja (när programmet startas upp) med att stänga Socket'en.
ClientSocket1->Socket->Close();

Sedan öppnar jag som beskrivit ovan. Blir det skit stänger jag Socket'en i On_Error eventen och nollar felkoden så jag släpper en massa felrutor. Jag noterar även det i en logg men det är en annan sak.

Efter jag har öppnat Socket'en väntar jag upp till 3000ms medan ClientSocket1->Socket->Connected blir kollad var 100ms. Blir den OK i tid fortsätter systemet med att kommunicera, annars signaleras det om att det inte gick och att nästa enhet ska kopplas upp.

Jag paketerar mina bytes i ett paket som skickas medelst:
ClientSocket1->Socket->SendBuf(Source, Bytes);

Och läser dom:
Length = ClientSocket1->Socket->ReceiveLength();
ClientSocket1->Socket->ReceiveBuf(Rx_Data.Bytes + Offset, Length);

Jag har just nu serieportsservern ställd som RS232 och loopat Rx & Tx varför jag får samma bytes som jag skickar. Och det fungerar riktigt bra nu, faktisk så väl att jag måste sänka hastigheten lite - ett angenämt problem.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43150
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: BCB6 hjälp med sockets

Inlägg av sodjan »

Trevligt! Jag/vi har ett system där vi kommunicerar mot olika utrustningar på ungefär samma sätt. Dock via vad som motsvarar emaljerade COM portar så vi har ingen direkt socket hantering i koden.

Det är nog 30-40 serieports servers med 2-4 portar på varje (liknande de du har) och 40-50 PLC som vi kör direkt mot. En bakgrundsprocess för varje utrustning (enklare att starta om en enskild linje på det sättet).

He he, ser att rättstavningen i telefonen fick med lite humor också ovan, jag låter det vara kvar... ☺️
Skulle vara emulerade COM portar, så klart...
Skriv svar