Hi mensen,
Ik heb gehoord dat ik hier ook gewoon mijn C vragen neer mag zetten, dus ja dan maar dit:

Ik ben dus nu samen met Steven met een spel bezig, heb al een leuk beginnetje. OOK qua socket server.

Ik heb nu dit voor de client (word binnenkort Flash):


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

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

int main(int argc, char *argv[])
{
    int sockfd, portno, n;
    struct sockaddr_in serv_addr;
    struct hostent *server;

    char buffer[256];
    if (argc < 3) {
       fprintf(stderr,"usage %s hostname port\n", argv[0]);
       exit(0);
    }
    portno = atoi(argv[2]);
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    if (sockfd < 0)
        error("ERROR opening socket");
    server = gethostbyname(argv[1]);
    if (server == NULL) {
        fprintf(stderr,"ERROR, no such host\n");
        exit(0);
    }
    bzero((char *) &serv_addr, sizeof(serv_addr));
    serv_addr.sin_family = AF_INET;
    bcopy((char *)server->h_addr,
         (char *)&serv_addr.sin_addr.s_addr,
         server->h_length);
    serv_addr.sin_port = htons(portno);
    if (connect(sockfd,&serv_addr,sizeof(serv_addr)) < 0)
        error("ERROR connecting");
    printf("Het bericht: ");
    bzero(buffer,256);
    fgets(buffer,255,stdin);
    n = write(sockfd,buffer,strlen(buffer));
    if (n < 0)
         error("ERROR writing to socket");
    bzero(buffer,256);
    n = read(sockfd,buffer,255);
    if (n < 0)
         error("ERROR reading from socket");
    printf("%s\n",buffer);
    return 0;
}




En de Server (nog geen vast draaiend proces, maar goed):


#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[])
{
     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");
     printf("Het bericht: %s\n",buffer);
     n = write(newsockfd,"Ik heb uw bericht. ",18);
     if (n < 0) error("ERROR writing to socket");
     return 0;
}



Zoals de C kunners zien doet het dit:

Ik start de server:
./socketserver 5555
(port is 5555)
en de client:
./socketclient localhost 5555

er word dan om een bericht gevraagd, ik typ bericht in, druk op enter en ik krijg de melding: 'Ik heb uw bericht' Op de server zie ik dan: het bericht: blaat (of dergelijke)

Nu wil ik er dus een ECHTE socket server van maken:
1: dat na ik een bericht heb gestuurd, niet mijn socket server afsluit (oftewel: hoe maak ik er een proces van.. een deamon)
2: dat het bericht aan alle clients word laten zien die op dat moment naar de socket server luisteren.
Weet iemand hoe ik die 2 punten moet doen?

Mijn systeem: FreeBSD unix

MvG,
Niek

[edit]
typo
[/edit]
[edit]
typo
[/edit]
[edit]
typo
[/edit]
[edit]
Paar dingen erbij gezet
[/edit]
hm, ja dat is iets om te onthouden denk ik ja!
Heeft u nog iedeeën voor mijn vragen verder? (of iemand anders)
ow, da klinkt nog vrij simpel, gewoon alles letterlijk doorsturen?

Da staat al letterlijk op die link zelfs:


/*
** selectserver.c -- a cheezy multiperson chat server
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#define PORT 9034   // port we're listening on

int main(void)
{
    fd_set master;   // master file descriptor list
    fd_set read_fds; // temp file descriptor list for select()
    struct sockaddr_in myaddr;     // server address
    struct sockaddr_in remoteaddr; // client address
    int fdmax;        // maximum file descriptor number
    int listener;     // listening socket descriptor
    int newfd;        // newly accept()ed socket descriptor
    char buf[256];    // buffer for client data
    int nbytes;
    int yes=1;        // for setsockopt() SO_REUSEADDR, below
    socklen_t addrlen;
    int i, j;

    FD_ZERO(&master);    // clear the master and temp sets
    FD_ZERO(&read_fds);

    // get the listener
    if ((listener = socket(PF_INET, SOCK_STREAM, 0)) == -1) {
        perror("socket");
        exit(1);
    }

    // lose the pesky "address already in use" error message
    if (setsockopt(listener, SOL_SOCKET, SO_REUSEADDR, &yes,
                                                        sizeof(int)) == -1) {
        perror("setsockopt");
        exit(1);
    }

    // bind
    myaddr.sin_family = AF_INET;
    myaddr.sin_addr.s_addr = INADDR_ANY;
    myaddr.sin_port = htons(PORT);
    memset(&(myaddr.sin_zero), '\0', 8);
    if (bind(listener, (struct sockaddr *)&myaddr, sizeof(myaddr)) == -1) {
        perror("bind");
        exit(1);
    }

    // listen
    if (listen(listener, 10) == -1) {
        perror("listen");
        exit(1);
    }

    // add the listener to the master set
    FD_SET(listener, &master);

    // keep track of the biggest file descriptor
    fdmax = listener; // so far, it's this one

    // main loop
    for(;;) {
        read_fds = master; // copy it
        if (select(fdmax+1, &read_fds, NULL, NULL, NULL) == -1) {
            perror("select");
            exit(1);
        }

        // run through the existing connections looking for data to read
        for(i = 0; i <= fdmax; i++) {
            if (FD_ISSET(i, &read_fds)) { // we got one!!
                if (i == listener) {
                    // handle new connections
                    addrlen = sizeof(remoteaddr);
                    if ((newfd = accept(listener, (struct sockaddr *)&remoteaddr,
                                                             &addrlen)) == -1) { 
                        perror("accept");
                    } else {
                        FD_SET(newfd, &master); // add to master set
                        if (newfd > fdmax) {    // keep track of the maximum
                            fdmax = newfd;
                        }
                        printf("selectserver: new connection from %s on "
                            "socket %d\n", inet_ntoa(remoteaddr.sin_addr), newfd);
                    }
                } else {
                    // handle data from a client
                    if ((nbytes = recv(i, buf, sizeof(buf), 0)) <= 0) {
                        // got error or connection closed by client
                        if (nbytes == 0) {
                            // connection closed
                            printf("selectserver: socket %d hung up\n", i);
                        } else {
                            perror("recv");
                        }
                        close(i); // bye!
                        FD_CLR(i, &master); // remove from master set
                    } else {
                        // we got some data from a client
                        for(j = 0; j <= fdmax; j++) {
                            // send to everyone!
                            if (FD_ISSET(j, &master)) {
                                // except the listener and ourselves
                                if (j != listener && j != i) {
                                    if (send(j, buf, nbytes, 0) == -1) {
                                        perror("send");
                                    }
                                }
                            }
                        }
                    }
                } // it's SO UGLY!
            }
        }
    }
    
    return 0;
} 
ahh, ja. die werkt nu.. heb nu ook al een klein client scriptje (zie boven) maar die werkt dus nu weer niet op déze socket server. Weet u wat voor client ik moet maken?
Hmm, is dat de moeite waard als je toch de boel in flash gaat hangen? Dan kun je beter gewoon even telnet gebruiken ofzo.
het moet uiteindelijk ook flash worden, maar eerst moet alles in C getest worden... Ik moet dus eventjes een C voorbeeld hebben ;)
Het is dan wel nogal zonde van alle tijd die in je C code gaat zitten, mja... :P Het punt is namelijk dat je invoer van buiten wilt kunnen hebben en tegelijkertijd ontvangen, dus moet je met threads gaan werken enzo
hmm, is het veel werk dan alleen voor een tesT? heeft u anders een flash voorbeeld? het moet uiteindelijk tog in flash komen ;-)
Als ik eerlijk ben heb ik nooit met Flash ActionScript gewerkt...
hm, de test is nu klaar!

Maar weet iemand of het mogelijk is om C aan een MySQL database te koppelen? ik wil namelijk wegsgrijven wanneer er iemand is 'geconnect' naar mijn server.. kan dit? weet iemand daT?

Groeten,

Reageren