Gå til innhold

FAQ: 4.7 - Hvordan programmere nettverk/sockets i Linux?


Anbefalte innlegg

[Til FAQ'en]

 

FAQ: 4.7 - Hvordan programmere nettverk/sockets i Linux?

 

Fyr opp favoritteditoren din og skriv inn denne koden for serveren:

 

   /*

   ** server.c -- a stream socket server demo

   */



   #include <stdio.h>

   #include <stdlib.h>

   #include <unistd.h>

   #include <errno.h>

   #include <string.h>

   #include <sys/types.h>

   #include <sys/socket.h>

   #include <netinet/in.h>

   #include <arpa/inet.h>

   #include <sys/wait.h>

   #include <signal.h>



   #define MYPORT 3490    // the port users will be connecting to



   #define BACKLOG 10     // how many pending connections queue will hold



   void sigchld_handler(int s)

   {

       while(wait(NULL) > 0);

   }



   int main(void)

   {

       int sockfd, new_fd;  // listen on sock_fd, new connection on new_fd

       struct sockaddr_in my_addr;    // my address information

       struct sockaddr_in their_addr; // connector's address information

       socklen_t sin_size;

       struct sigaction sa;

       int yes=1;



       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

           perror("socket");

           exit(1);

       }



       if (setsockopt(sockfd,SOL_SOCKET,SO_REUSEADDR,&yes,sizeof(int)) == -1) {

           perror("setsockopt");

           exit(1);

       }

       

       my_addr.sin_family = AF_INET;         // host byte order

       my_addr.sin_port = htons(MYPORT);     // short, network byte order

       my_addr.sin_addr.s_addr = INADDR_ANY; // automatically fill with my IP

       memset(&(my_addr.sin_zero), '', 8); // zero the rest of the struct



       if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr))

                                                                      == -1) {

           perror("bind");

           exit(1);

       }



       if (listen(sockfd, BACKLOG) == -1) {

           perror("listen");

           exit(1);

       }



       sa.sa_handler = sigchld_handler; // reap all dead processes

       sigemptyset(&sa.sa_mask);

       sa.sa_flags = SA_RESTART;

       if (sigaction(SIGCHLD, &sa, NULL) == -1) {

           perror("sigaction");

           exit(1);

       }



       while(1) {  // main accept() loop

           sin_size = sizeof(struct sockaddr_in);

           if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr,

                                                          &sin_size)) == -1) {

               perror("accept");

               continue;

           }

           printf("server: got connection from %sn",

                                              inet_ntoa(their_addr.sin_addr));

           if (!fork()) { // this is the child process

               close(sockfd); // child doesn't need the listener

               if (send(new_fd, "Hello, world!n", 14, 0) == -1)

                   perror("send");

               close(new_fd);

               exit(0);

           }

           close(new_fd);  // parent doesn't need this

       }



       return 0;

   } 

 

..og denne koden for klienten:

 

   /*

   ** client.c -- a stream socket client demo

   */



   #include <stdio.h>

   #include <stdlib.h>

   #include <unistd.h>

   #include <errno.h>

   #include <string.h>

   #include <netdb.h>

   #include <sys/types.h>

   #include <netinet/in.h>

   #include <sys/socket.h>



   #define PORT 3490 // the port client will be connecting to 



   #define MAXDATASIZE 100 // max number of bytes we can get at once 



   int main(int argc, char *argv[])

   {

       int sockfd, numbytes;  

       char buf[MAXDATASIZE];

       struct hostent *he;

       struct sockaddr_in their_addr; // connector's address information 



       if (argc != 2) {

           fprintf(stderr,"usage: client hostnamen");

           exit(1);

       }



       if ((he=gethostbyname(argv[1])) == NULL) {  // get the host info 

           perror("gethostbyname");

           exit(1);

       }



       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {

           perror("socket");

           exit(1);

       }



       their_addr.sin_family = AF_INET;    // host byte order 

       their_addr.sin_port = htons(PORT);  // short, network byte order 

       their_addr.sin_addr = *((struct in_addr *)he->h_addr);

       memset(&(their_addr.sin_zero), '', 8);  // zero the rest of the struct 



       if (connect(sockfd, (struct sockaddr *)&their_addr,

                                             sizeof(struct sockaddr)) == -1) {

           perror("connect");

           exit(1);

       }



       if ((numbytes=recv(sockfd, buf, MAXDATASIZE-1, 0)) == -1) {

           perror("recv");

           exit(1);

       }



       buf[numbytes] = '';



       printf("Received: %s",buf);



       close(sockfd);



       return 0;

   } 

 

Kompiler hver av dem og start først serveren, så starter du klienten:

./client localhost

 

Hvis du starter serveren på en annen maskin, f.eks. en med ip 10.0.0.139, starter du klienten slik:

./client 10.0.0.139

 

<forklare hvordan koden fungerer her>

Koden er tatt fra: http://www.ecst.csuchico.edu/~beej/guide/n...html/index.html (released som public domain, for de som lurer) der du vil finne en engelsk forklaring og tutorial.

Må også ha med litt om ACE og andre vanlige socket-libs.

 

 

Kanskje ikke så intressant i en FAQ, men keg jobber med et C++ API for nettverk/socket-programmering som skal være enklere å bruke for nybegynnere (og meg selv), jeg poster mer om dette her siden.

Lenke til kommentar
  • 4 måneder senere...
Videoannonse
Annonse

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...