c++ || sys/socket.h (select x2 (sender och receiver select socket) || Smart sätt att sköta "pairingen" mellan sockets

Permalänk
Medlem

c++ || sys/socket.h (select x2 (sender och receiver select socket) || Smart sätt att sköta "pairingen" mellan sockets

Hej SweC.

Så ni kanske har sätt någon av mina många trådar gällande sys/socket.h. Iaf jag kom fram till att jag gjort en dålig metod (använda induella trådar för varje en skild socket (vart för många trådar och cracha servern)) Så nu har jag tänkt om min server har nu två "mastersockets" som använder select (konceptuellt kan ni se denna sida) för nya anslutning osv. dvs bara två trådar: en för mastersocket för skicka till client och en för mastersocket som tar emot från client. Då jag nu skulle vilja "paira" skicka och ta emot sockets för en specifik client så känner jag att de metoderna jag har kommit fram till (se nedan) är lite långsökta och att det borde finnas bättre metod. Är det så att någon har en bättre metod skriv gärna ner det i tråden.

Min metod går nu ut på att innan resten av programmet kan skicka/(ta emot) till en client så måste server genomföra en pairing som görs på följande sätt (repeteras varje gång när ett nytt meddelande ska skickas eller tas emot):

  1. (Server): kollar upp alla icke "pairade" skicka subsocket's.

  2. (Server): till varje icke pairade som hittas skickas då: "Token:[ServersSkickaSubsocketIndex]:[RandomgenereratNummer]:xxyyxx:" (detta meddelande sparas tills pair med det är gjort).

  3. (Client): ta emot meddelandet (Token:[ServersSkickaSubsocketIndex]:[RandomgenereratNummer]:xxyyxx:)

  4. (Client): Skickar tillbaka samma meddelande till servern på clientens skicka socket.

  5. (Server): Upptäck all icke "pairade" ta emot subsocket's

  6. (Server): Kolla om den fått ett "token" meddelande från en eller flera av subsocket's (om ja gå vidare, om nej "return")

  7. (Server): Parsa ut [ServersSkickaSubsocketIndex].

  8. (Server): Hitta Skickar subsocket:en och kontrollera att "token" meddelandet den skicka är det samma som den tog emot

  9. (Server): Om steget innan ja: spara att dessa två subsockets är till samma client, annars logga och return.

Tack för eventuell hjälp!

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Permalänk

Varför är du tvungen att ha en socket för att läsa och en socket för skriva? Varför läser och skriver du inte på samma?

Permalänk
Medlem

Det ända sättet jag har fått det att fungera "bra" är via att gör två trådar en send och en ta emot tråd för samma socket alternativt non-blocket socket. Båda dessa metoder har då gjort att CPU:n på servern fått för mycket trådar (leder till att CPU jobbar sönder sig själv), jag testade med att "söva" trådarna någon milli sek när de inte hade något att göra, men så fort man ökar klienterna från 1 till 3-4 så blev det otroligt mycket CPU användning hur som helst. Troligen så går det bra med en socket per client, bara jag som inte hittat en bra lösning på detta där full duplex fungerar.

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6

Permalänk
Medlem

Nu har jag inte sysslat seriöst med socketprogrammering i C de senaste 10 åren, men jag hade gjort följande i din situation:

- Börjat med att glömma allt som har med mer än en socket per klient att göra. TCP och sockets är dubbelriktade och de ska användas så.

- Börjat med en singeltrådad server och sedan utökat den med multitrådning när behov faktiskt uppstår.

Koden i det du länkade till bör fungera bra att utgå ifrån:

1) Anropa select(2)
2) Kolla om du behöver göra accept(2) på det du kallar "master-socket", dvs ifall en ny klient ansluter.
3) Kolla om någon kopplade ner, anropa i så fall close(2)
4) Läs ut data som kom in från klient med recv(2), parsa och se om hela meddelandet har kommit in än, om inte hantera det genom att spara undan den utlästa datan - resten av meddelandet kommer antagligen efter nästa select(2).
5) Agera på fullständigt mottaget meddelande, processa och skriv tillbaka svaret med send(2)
6) Kolla om något server-event har hänt för respektive klient, i så fall sklicka meddelande med send(2)

Efter hand skulle man kunna lägga in punkt 4 och 5 i egna trådar som man skapar från huvudtråden när meddelanden kommer in (om man klarar av trådsynkroniseringen...). Punkt 6 kan också gå i en eller flera egna trådar.

En singeltrådad server som gör väldigt lite processning, till exempel echo-servern i ditt exempel, ska kunna skala till tiotals om inte hundratals klienter så länge man kör rimlig mängd meddelanden.

Permalänk
Medlem

Ja, det där låter inte helt dumt. Får testa det om/när jag hittar problem med nuvarande.

Tack för förslaget!

Visa signatur

Смерть -это решение всех проблем. Нет человека - нет проблемы
Comp1: Ubuntu 16.04 Comp2: Arch Linux
Comp3: Ubuntu Server 16.04 Comp4: Centos 6.5
Comp5: Linux mint 16 Comp6: Raspberry pi (olika OS hela tiden)
Phone: Motorola Google Nexus 6