Gå til innhold

Innloggingsfunksjon for server


Anbefalte innlegg

Holder på å skrive et server-program i C.

 

Jeg trenger en innloggingsfunksjon som sammenligner brukernavn/passord(md5-krypter) fra socket med en liste i en tekstfil, med et format som ligner apache sine passwd-filer. Noen som har link til guide for dette, eller eksempler?

 

BTW, lærer meg C++ for tiden. Noen som har link til guide for socket-programmering i C++?

 

Her er koden så langt (for det meste kopiert fra en nettside, men jeg forstår det meste av den ;) ):

 

#include <stdio.h>
#include <sys/types.h> 
#include <sys/socket.h>
#include <netinet/in.h>

void error(char *msg)
{
   perror(msg);
   exit(1);
}

int main(int argc, char *argv[])
{
printf("mmorpg_01 server 0.1.1\n");
    int sockfd, newsockfd, portno, clilen;
    char buffer[256];
    struct sockaddr_in serv_addr, cli_addr;
    int n;
if (argc < 2)
{
 fprintf(stderr,"ERROR, no port provided\n");
 exit(1);
}
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
{ 
 error("ERROR opening socket");
}
bzero((char *) &serv_addr, sizeof(serv_addr));
portno = atoi(argv[1]);
    serv_addr.sin_family = AF_INET;
    serv_addr.sin_addr.s_addr = INADDR_ANY;
    serv_addr.sin_port = htons(portno);
if(bind(sockfd,(struct sockaddr *) &serv_addr,sizeof(serv_addr)) < 0)
{
 error("ERROR on binding");
}
listen(sockfd,5);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);
if(newsockfd < 0)
{
 error("ERROR on accept");
}
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0)
{
 error("ERROR reading from socket");
}
if(!strcmp(buffer,"CON 0"))
{
 printf("Recieved connection from %s\n",inet_ntoa(cli_addr.sin_addr));
 n = write(newsockfd,"CON 1",18);
 if (n < 0) error("ERROR writing to socket");
}
//printf("Here is the message: %s\n",buffer);
bzero(buffer,256);
n = read(newsockfd,buffer,255);
if (n < 0)
{
 error("ERROR reading from socket");
}
if(!strcmp(buffer,"LOGIN tg90nor 0"))
{
 printf("%s logged in\n",inet_ntoa(cli_addr.sin_addr));
 n = write(newsockfd,"LOGIN 1",18);
 if (n < 0) error("ERROR writing to socket");
}
return 0; 
}

Lenke til kommentar
Videoannonse
Annonse

For sliten til å se nærmere på koden din, men du kan finne en god guide til socket programmering her (beej.us)

Den blir bl.a. anbefalt i noen kurs på blindern. Kanskje litt avansert hvis du ikke har programmert før og skal lære deg C++, men tror det skulle gå bra.

 

Forresten, du bør ikke bruke bzero, men heller memset(buffer, '\0', lengde)...

 

[EDIT]

Jeg var visst litt mer søvnig enn zirener, som slo meg med et par sekunder...

Men artig at vi begge anbefalte samme guide uavhengig av hverandre :)

[/EDIT]

Endret av Mr.Garibaldi
Lenke til kommentar

Du kan jo gjøre noe alà dette:

Klient:

socket()
gethostbyname()  //eller noe
initialiser sockaddr_in instansen som refererer til localhost;
while true {
       listen()
       accept()
       fork() {
              send()    
              recv()   //Det du mottar er vel kansje kryptert. Dette må isåfall dekrypteres.
       }
       cleanup
}

Ja, tror du skjønner tegninga :)

Lenke til kommentar

Ellers kan du ta utgangspunkt i select() eksempelet fra Beej, og bare bruke fork() når du har funksjoner som vil ta lang tid på å eksekvere. (Og hvis du trenger å returnere data kan du enten sende det via en lokal socket, eller bruke en mailbox)

 

Det er noe vanskeligere enn bare å bruke fork(), men du vil spare ressurser på serveren, noe som kan være lurt hvis du skal lage en MMORPG..

Lenke til kommentar

fork lager en helt ny prosess, noe som er unødvendig og vanskeliggjør ting. Det man ønsker å bruke er tråder.

 

Unix/linux:

NAME
      pthread_create - create a new thread


SYNOPSIS
      #include <pthread.h>

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

.......

SEE ALSO
      pthread_exit(3), pthread_join(3), pthread_detach(3), pthread_attr_init(3).

 

For å holde orden på data når man har flere tråder gående, så trenger man semaforer:

 

NAME
      sem_init, sem_wait, sem_trywait, sem_post, sem_getvalue, sem_destroy - operations on semaphores


SYNOPSIS
      #include <semaphore.h>

      int sem_init(sem_t *sem, int pshared, unsigned int value);

      int sem_wait(sem_t * sem);

      int sem_trywait(sem_t * sem);

      int sem_post(sem_t * sem);

      int sem_getvalue(sem_t * sem, int * sval);

      int sem_destroy(sem_t * sem);

....

SEE ALSO
      pthread_mutex_init(3), pthread_cond_init(3), pthread_cancel(3), ipc(5).

 

Eller så bruker man pthread_mutex, som jeg tror er noe enklere.

 

Prosess: Et eget program, med egen prosessid

Tråd: Tråder kjører parallelt innenfor samme prosess. Det betyr at, for eksempel, en tråd kan vente på nye kontakter, og en annen tråd holder orden på de kontakter som allerede finnes.

Semafor og mutex: Sørger for at bare en tråd av gangen kan modifisere data som er delt mellom de forskjellige trådene. Har man for eksempel en tråd som venter på nye brukere og legger dem til i en liste over brukere, og en tråd som bruker listen til noe annet, så trenger man en semafor for at bare en av dem bruker listen samtidig. Hvis ikke blir det fort kræsj i systemet.

 

NB! Dette er ikke nybegynner-konsept. Er du fersk på programmering, så anbefaler jeg å begynne litt enklere. Sette delmål og sakte utvide konseptet.

Lenke til kommentar

Har allerede en server som aksepterer flere tilkoblinger, gjennom fork. (skal forresten titte på threads, noen bra guider der ute?)

Serveren og klienten har kontakt og er i stand til å sende meldinger til hverandre.

 

Det jeg sliter med nå er følgende problem:

 

Klienten sender et brukernavn og et passord til serveren. Om de er feil, sender serveren en melding tilbake til klienten, og lukker tilkoblingen.

 

Hvordan får jeg serveren til å sjekke om brukernavn/passord stemmer uten å bruke en million strcmp()er?

Lenke til kommentar

Om du bruker fork, hvordan kommuniserer de forskjellige prosessene med hverandre?

 

Ellers så skjønner jeg ikke problemstillingen med brukernavn/passord. Er ikke det rett frem?

Du leser inn fila med brukere og (hashet) passord. Så finner du riktig bruker og henter (det hashede) passordet. Så sammenligner du dette med (hash'en) til passordet som bruker skriver.

Lenke til kommentar
Om du bruker fork, hvordan kommuniserer de forskjellige prosessene med hverandre?

http://beej.us/guide/bgnet/output/html/cli...ml#simpleserver

Ellers så skjønner jeg ikke problemstillingen med brukernavn/passord. Er ikke det rett frem?

Du leser inn fila med brukere og (hashet) passord. Så finner du riktig bruker og henter (det hashede) passordet. Så sammenligner du dette med (hash'en) til passordet som bruker skriver.

5271327[/snapback]

Jo, det virker ganske enkelt, men jeg finner ikke kode for akkurat det. Har lett masse, uten resultat. Kunne trengt et eksempel, om så bare litt pseudo-kode, så skulle jeg nok få det til.

Lenke til kommentar
Om du bruker fork, hvordan kommuniserer de forskjellige prosessene med hverandre?

http://beej.us/guide/bgnet/output/html/cli...ml#simpleserver

 

Du er klar over at hver prosses i det eksempelet lever i sin egen lille verden og ikke kommuniserer med hverandre, bare med hver sin klient?

 

Ellers så skjønner jeg ikke problemstillingen med brukernavn/passord. Er ikke det rett frem?

Du leser inn fila med brukere og (hashet) passord. Så finner du riktig bruker og henter (det hashede) passordet. Så sammenligner du dette med (hash'en) til passordet som bruker skriver.

5271327[/snapback]

Jo, det virker ganske enkelt, men jeg finner ikke kode for akkurat det. Har lett masse, uten resultat. Kunne trengt et eksempel, om så bare litt pseudo-kode, så skulle jeg nok få det til.

5271353[/snapback]

 

Hvis du tar en titt på denne tråden, så ser du et (dog ikke-fungerende) eksempel på hvordan det kan gjøres. Hvis du leser hele tråden skulle du få en ide til hvordan gjøre det.

Lenke til kommentar
Du er klar over at hver prosses i det eksempelet lever i sin egen lille verden og ikke kommuniserer med hverandre, bare med hver sin klient?

Ja, men det er heller ikke nødvendig på det nåværende tidspunkt. Skal kikke mer på det litt senere.

Hvis du tar en titt på denne tråden, så ser du et (dog ikke-fungerende) eksempel på hvordan det kan gjøres. Hvis du leser hele tråden skulle du få en ide til hvordan gjøre det.

5271455[/snapback]

Fikk en viss idè ja. Skal teste litt etter skolen.

Lenke til kommentar

Jeg stussa også på den først, men antar spørsmålet dreier seg om c++ klasser som håndterer sockets, slik at man slipper å foholde seg til unix-varianten. Finnes sikkert noen bibliotek for det, men jeg har ikke oversikten.

 

En mulighet er hvis man benytter seg av QT, så har QT egne klasser for nettverksprogrammering: http://doc.trolltech.com/4.0/q3socket.html

 

Men QT er overkill om man skal lege en enkel klient/server og ikke har bruk for alt det andre som følger med. Fordelen med QT er derimot at du kan bruke samme programmet på Windows og Linux med minimale endringer.

Lenke til kommentar

Dersom det er tilfelle anbefaler at du prøver å lage din egen socket klasse. Det er ikke spesielt vanskelig, og det er ikke store endringer som skal til for å få den til å funke på både linux og windows.

Sockets var noe av det første jeg gjorde da jeg begynte med C++ (lagde en irc bot), klarte jeg det, klarer du det.

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å
  • Hvem er aktive   0 medlemmer

    • Ingen innloggede medlemmer aktive
×
×
  • Opprett ny...