Gå til innhold

Anbefalte innlegg

Jeg driver og skriver en multi-thread server, og har en thread som "lytter" etter ny tilkoblinger. Når noen kobler til, så vil jeg at serveren skal starte opp en ny thread og overføre "tilkoblingen" til den, slik at den nye threaden kontrollerer all inn og utgående trafikk for den socketen. Hvordan kan dette gjøres?

 

På forhånd takk

Lenke til kommentar
Videoannonse
Annonse

Dette kommer jo ganske an på hvordan du gjør trådprogrammeringen, trådprogrammering er ikke noen del av C/C++ i seg selv. Jeg har ikke særlig peil på sockets, men kan du ikke bare opprette socketen i hovedfunksjonen, og gi et objekt med nødvendig informasjon til en tråd som opprettes? Denne tråden kan da bare lytte på socketen i sin funksjon (du er vel klar over at hver tråd eksekverer innenfor en viss funksjon)?

Eller socketen kan kanskje opprettes i tråden, alt ettersom, poenget er uansett at den nye tråden kun trenger nødvendig informasjon.

Lenke til kommentar

du kan kjøre PThread...

 

Dette burde også funke fint i windows.. siden M$ skryter på seg at win2k og senere skal være postix kompatible, også er det ganske lett å få til å funke med PThread :D

Hvis ikke kan du fork & ecec hvis du kjører *nix

Lenke til kommentar

Da må du vel først ha en pthread-implementasjon for den aktuelle plattformen? Linux har sin implementasjon etc. Så vidt jeg forsto fantes det en Win32-port av pthread, fra Redhat eller noe, men ikke hørt så mye om det på en stund.

Lenke til kommentar

Mitt råd er å ikke bruke pthreads hvis Win32 er din platform. Da ville jeg brukt enten Win32 API eller Boosts platformuavhengige thread implementasjon.

 

Du kan også bruke ATL eller MFC sine wrappere hvis du har mulighet til det, men selv foretrekker jeg å bruke mine egne basert på APIen.

 

Boost kan du forøvrig finne her: www.boost.org (inneholder også mye annet snacks :)

Lenke til kommentar

Men hva er det du trenger å vite, hvordan du oppretter en tråd, eller hvordan du "overfører" forbindelsen til tråden? Så vidt jeg vet kan en pthread få et vilkårlig objekt (i form av en void *), her burde du kunne sende den alt av informasjon (i en struct) den trenger for å åpne en socket.

Lenke til kommentar

Jeg har en thread som åpner en port og lytter etter innkommende tilkoblinger, og når noen kobler til så starter jeg opp en ny thread som skal håndtere all kommunikasjon med den tilkoblingen. Jeg overfører socketen til den nye threaden, men problemet er at den nye threaden ikke kan sende noe til socketen, og heller ikke stenge den. Tror det er fordi en thread ikke har tilgang til å bruke noe som tilhører en annen thread.

 

Vet det er mange programmer som bruker threads på denne måten, så det er fult mulig, men antakelig må det gjøres på en annen måte enn å bare sende socketen som et argument til den nye threaden.

Lenke til kommentar

Altså, en tråd har neppe eksplisitt eierskap til en socket, men kan du ikke bare gi tilstrekkelig info når du oppretter tråden, slik at den selv kan opprette en socket? Har ikke så peil på sockets, men er det noe i veien for at tråden selv oppretter socketen?

Edit: Kanskje dette har noe med hvordan trådimplementasjonen funker, og at hver tråd faktisk er en prosess, og socketen er knyttet til prosessid (skal ikke se bort ifra det). Men kan du ikke få en feilmelding, eller på en eller annen måte probe hvorfor tråden ikke får brukt socketen?

Lenke til kommentar
Men kan du ikke få en feilmelding, eller på en eller annen måte probe hvorfor tråden ikke får brukt socketen?

 

Feilmeldingen er at SEND returnerer "-1" når den brukes i threaden, altså den kan ikke sende til socketen.

Lenke til kommentar

Er vist noe problemer med errno og threads.. må bruke en modifisert versjon for at de skal funke. Kan heller ikke kalle "cout" fra threaden fordi programmet kjører i background, så jeg må få threaden til å skrive det til en fil. Jeg kan prøve og gjøre dette hvis du tror at den feilmeldingen er viktig.

Lenke til kommentar

Hvis du skriver C++, ville det kanskje være til hjelp å bruke et objektorientert bibliotek. Skal ikke se bort ifra at det ville gjøre ting enklere (så man slipper å gjøre noen av de samme feilene som andre før). ACE har klasser for både nettverk og tråding, så jeg ville i alle fall sjekket ut det.

Men errno er nok god å ha, for å finne ut akkurat hva som går galt. Og ... Hvis tingen er at en tråd ikke får lov til å benytte en socket opprettet i en annen tråd, hvorfor ikke bare opprette en ny socket i selve tråden?

Lenke til kommentar

En thread lytter etter innkommende tilkobliger som jeg har sagt. Kan ikke ha flere threads som lytter på den samme porten, og når noen kobler til så vil det bli en ny socket i den threaden som lytter. Jeg må da overføre socketen til den nye threaden. Har ikke mulighet for å opprette socketen i den nye threaden i og med at threaden blir laget på grunn av socketen og ikke omvendt.

 

Men jeg kan prøve noen ferdige bibliotek for threads og sockets som du foreslo. Mulig at noen har løst dette problemet på en måte som kan gjøre det lett å legge inn i programmet mitt.

Lenke til kommentar

Altså, er ikke inni C++, men tankegangen er vel rimelig lik Java. Du har et objekt som lytter etter tilkoblinger. Dersom det kommer en tilkobling så starter dette objektet en tråd med socketen som ble opprettet som argument...etter det tar tråden seg av hele kommunikasjonen med denne ene klienten. "Lytter"-objektet går tilbake til å lytte etter flere tilkoblinger. Er det noe jeg misforstod her, eller svarte jeg på spørsmålet? :)

Lenke til kommentar

Skjer automatisk? Hva mener du? Altså den klassen som lytter etter klientene går i en evig loop. Dersom en klient kobler seg til så startes tråden. Kan som sagt ikke C++, men her har du et eksempel i Java:

        

ServerSocket tjener = new ServerSocket(portnr);

while (true) 

       {

     System.out.println("Logg for tjener: Venter på anrop fra klientene.");

          Socket forbindelse = tjener.accept(); //lytter etter klient 

          Thread klienttråd = new TraadHaandterer(forbindelse);

          klienttråd.start();

                     

          

       }

Koden i klienttråd er da den som tar seg av hver enkelt klient, mens objektet som lytter går inn i en ny loop der den står og "henger" (tjener.accept()) og venter på ny tilkobling.

Lenke til kommentar

Riktig tankegang smetho.

 

Det skal ikke være noe problem å sende inn det du trenger av informasjon til tråden som argument i pthread_create() funksjonen.

 

Prototypen for pthread_create() er:


int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void), void *arg);

Da skulle det vel være mulig å sende inn informasjonen i arg parameteren?

 

Du lager f.eks. din egen klasse MyThreadParams og en thread proxy funksjon:


class MyThreadParams

{

public:

   void run()

   {

       //do what you want here :)

   }



private:

   //your socket vars..

};





static void* thread_proxy(void* param)

{

   assert(param);

   MyThreadParams *param = static_cast<MyThreadParams*>(param);

   param->run();

}

 

Dette er i hvertfall den vanlige måten å gjøre det på med Windows' tråd-api. Det er så lenge siden jeg brukte pthreads at jeg kan ikke huske så mange detaljer... ikke har jeg kompilator her jeg sitter heller. Men dette er ihvertfall slik jeg mener det bør være etter en rask googling :)

Lenke til kommentar
En thread lytter etter innkommende tilkobliger som jeg har sagt. Kan ikke ha flere threads som lytter på den samme porten, og når noen kobler til så vil det bli en ny socket i den threaden som lytter. Jeg må da overføre socketen til den nye threaden. Har ikke mulighet for å opprette socketen i den nye threaden i og med at threaden blir laget på grunn av socketen og ikke omvendt.
Jeg fant et eksempel på en enkelt multitrådet server i Linux, den viser at socketen blir opprettet i mortråden riktignok, men barnet ser ikke ut til å ha problemer med å benytte den. Se:

http://www.linuxsocket.org/books/Sockets/p...7/echo-thread.c

Men jeg kan prøve noen ferdige bibliotek for threads og sockets som du foreslo. Mulig at noen har løst dette problemet på en måte som kan gjøre det lett å legge inn i programmet mitt.

ACE-biblioteket burde ha det du ser etter.
Lenke til kommentar

Fikk det til nå. Feilen var at jeg hadde klart å skrevet feil når jeg skulle gjøre om fra void* til int i threaden. Det var ikke ulovlig så compileren ga ingen feil på det.

 

Beklager alt bryet jeg har skapt på grunn av en liten elementær skrivefeil av meg.

Lenke til kommentar

Opprett en konto eller logg inn for å kommentere

Du må være et medlem for å kunne skrive en kommentar

Opprett konto

Det er enkelt å melde seg inn for å starte en ny konto!

Start en konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...