Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
workshop:sockets [2010-09-29 19:50]
equinox
workshop:sockets [2015-09-16 12:41] (current)
Line 1: Line 1:
-====== Vortrag/​Workshop Einführung in Einführung ​Unix Socket Programmierung ======+====== Vortrag/​Workshop Einführung in Unix Socket Programmierung ======
  
   * by Christian Pointner   * by Christian Pointner
 +
 +
 +
 +
 +===== Beispielcode =====
 +
 +Es folgen ein paar simple Beispielprogramme die die Verwendung von Sockets unter Unix zeigen. Alle Beispiele und ein kleines Makefile können auch direkt per unten stehendem Link heruntergeladen werden:
 +
 +{{workshop:​socket-examples.tar.gz|socket-examples.tar.gz}}
 +
 +Es folgt noch der Code für einen sehr simplen Chat Server anhand dessen die Verwendung des Resolvers (DNS etc.) gezeigt wird.
  
 ==== Beispiel: udpclient ==== ==== Beispiel: udpclient ====
Line 53: Line 64:
   }   }
     ​     ​
-  struct sockaddr_in local_addr; 
-  memset((char *) &​local_addr,​ 0, sizeof(local_addr));​ 
-  local_addr.sin_family = AF_INET; 
-  local_addr.sin_port = htons(4321);​ 
-  local_addr.sin_addr.s_addr = htonl(INADDR_ANY);​ 
- 
-  if(bind(sock,​ (struct sockaddr *)&​local_addr,​ sizeof(local_addr))==-1) {  
-    perror("​bind() call failed"​);​ 
-    exit(-1); 
-  } 
- 
   struct sockaddr_in remote_addr;​   struct sockaddr_in remote_addr;​
   int alen, len;   int alen, len;
Line 93: Line 93:
   return 0;   return 0;
 } }
-</​file>/​*+</​file>​ 
 + 
 +==== Beispiel: udpserver ==== 
 + 
 +<​file>​ 
 +/*
  ​* ​ udpserver  ​* ​ udpserver
  *  *
Line 168: Line 173:
 </​file>​ </​file>​
  
 +==== Beispiel: tcpclient ====
  
 +<​file>​
 +/*
 + ​* ​ tcpclient
 + *
 + ​* ​ This is a very basic TCP client example to show the usage of
 + ​* ​ sockets. ​
 + ​*  ​
 + ​* ​ Copyright (C) 2010 Christian Pointner <​equinox@realraum.at>​
 + *
 + ​* ​ tcpclient is free software: you can redistribute it and/or modify
 + ​* ​ it under the terms of the GNU General Public License as published by
 + ​* ​ the Free Software Foundation, either version 3 of the License, or
 + ​* ​ any later version.
 + *
 + ​* ​ tcpclient is distributed in the hope that it will be useful,
 + ​* ​ but WITHOUT ANY WARRANTY; without even the implied warranty of
 + ​* ​ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ​ See the
 + ​* ​ GNU General Public License for more details.
 + *
 + ​* ​ You should have received a copy of the GNU General Public License
 + ​* ​ along with tcpclient. If not, see <​http://​www.gnu.org/​licenses/>​.
 + */
  
-==== Beispiel: ​udpserver ​====+#include <​stdio.h>​ 
 +#include <​stdlib.h>​ 
 +#include <​unistd.h>​ 
 +#include <​errno.h>​ 
 +#include <​string.h>​ 
 + 
 +#include <​sys/​types.h>​ 
 +#include <​sys/​socket.h>​ 
 + 
 +#include <​arpa/​inet.h>​ 
 + 
 +int main(int argc, char** argv) 
 +
 +  if(argc <= 2) { 
 +    fprintf(stderr,"​too few arguments\n"​);​ 
 +    exit(1); 
 +  } 
 +  printf("​starting TCP Client\n"​);​ 
 + 
 +  int sock = socket(AF_INET,​ SOCK_STREAM,​ 0); 
 +  if(sock < 0) {  
 +    perror("​socket() call failed"​);​ 
 +    exit(-1); 
 +  } 
 +     
 +  struct sockaddr_in remote_addr;​ 
 +  remote_addr.sin_family = AF_INET; 
 +  remote_addr.sin_port = htons(atoi(argv[2]));​ 
 +  if (inet_aton(argv[1],​ &​remote_addr.sin_addr)==0) { 
 +    perror("​inet_aton() call failed"​);​ 
 +    exit(-1); 
 +  } 
 + 
 +  if(connect(sock,​ (struct sockaddr *)&​remote_addr,​ sizeof(remote_addr))==-1) {  
 +    perror("​connect() call failed"​);​ 
 +    exit(-1); 
 +  } 
 + 
 +  int len; 
 +  uint8_t buffer[1500];​ 
 +  for (;;) { 
 +    if((len = read(0, buffer, 1500))==-1) { 
 +      perror("​read() call failed"​);​ 
 +      exit(-1); 
 +    } 
 + 
 +    int offset = 0; 
 +    int wlen; 
 +    for(;;) { 
 +      wlen = send(sock, &​buffer[offset],​ len - offset, 0); 
 +      if(wlen == -1) { 
 +        if(errno != EINTR) { 
 +          perror("​write() call failed"​);​ 
 +          exit(-1); 
 +        } 
 +        wlen = 0; 
 +      } 
 + 
 +      offset += wlen; 
 +      if(offset+1 >= len) 
 +        break; 
 +    } 
 +  } 
 + 
 +  close(sock);​ 
 +   
 +  printf("​exiting TCP Client\n"​);​ 
 + 
 +  return 0; 
 +
 +</​file>​ 
 + 
 +==== Beispiel: ​tcpserver ​====
  
 <​file>​ <​file>​
 +/*
 + ​* ​ tcpserver
 + *
 + ​* ​ This is a very basic TCP server example to show the usage of
 + ​* ​ sockets. ​
 + ​*  ​
 + ​* ​ Copyright (C) 2010 Christian Pointner <​equinox@realraum.at>​
 + *
 + ​* ​ tcpserver is free software: you can redistribute it and/or modify
 + ​* ​ it under the terms of the GNU General Public License as published by
 + ​* ​ the Free Software Foundation, either version 3 of the License, or
 + ​* ​ any later version.
 + *
 + ​* ​ tcpserver is distributed in the hope that it will be useful,
 + ​* ​ but WITHOUT ANY WARRANTY; without even the implied warranty of
 + ​* ​ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ​ See the
 + ​* ​ GNU General Public License for more details.
 + *
 + ​* ​ You should have received a copy of the GNU General Public License
 + ​* ​ along with tcpserver. If not, see <​http://​www.gnu.org/​licenses/>​.
 + */
 +
 +#include <​stdio.h>​
 +#include <​stdlib.h>​
 +#include <​unistd.h>​
 +#include <​errno.h>​
 +#include <​string.h>​
 +
 +#include <​sys/​types.h>​
 +#include <​sys/​socket.h>​
 +#include <​arpa/​inet.h>​
 +
 +#include <​sys/​select.h>​
 +
 +int main(int argc, char** argv)
 +{
 +  printf("​starting TCP Server\n"​);​
 +
 +  int server = socket(AF_INET,​ SOCK_STREAM,​ 0);
 +  if(server < 0) { 
 +    perror("​socket() call failed"​);​
 +    exit(-1);
 +  }
 +    ​
 +  struct sockaddr_in local_addr;
 +  memset((char *) &​local_addr,​ 0, sizeof(local_addr));​
 +  local_addr.sin_family = AF_INET;
 +  local_addr.sin_port = htons(1234);​
 +  local_addr.sin_addr.s_addr = htonl(INADDR_ANY);​
 +
 +  if(bind(server,​ (struct sockaddr *)&​local_addr,​ sizeof(local_addr))==-1) { 
 +    perror("​bind() call failed"​);​
 +    exit(-1);
 +  }
 +
 +  if(listen(server,​ 5)==-1) { 
 +    perror("​listen() call failed"​);​
 +    exit(-1);
 +  }
 +
 +  fd_set readfds, tmpfds;
 +  FD_ZERO(&​readfds);​
 +  FD_SET(server,​ &​readfds);​
 +  int max_fd = server;
 +  uint8_t buffer[1500];​
 +  struct sockaddr_in remote_addr;​
 +  memset (&​remote_addr,​ 0, sizeof(remote_addr));​
 +  int len, alen=sizeof(remote_addr);​
 +  for (;;) {
 +    memcpy(&​tmpfds,​ &​readfds,​ sizeof(tmpfds));​
 +    int num = select(max_fd+1,​ &​tmpfds,​ NULL, NULL, NULL);
 +    if(num == -1 && errno != EINTR) {
 +      perror("​select() call failed"​);​
 +      exit(-1);
 +    }
 +    if(num == -1 || !num)
 +      continue;
 +
 +    if(FD_ISSET(server,​ &​tmpfds)) {
 +      int new_client = accept(server,​ (struct sockaddr *)&​remote_addr,​ &alen);
 +      if(new_client==-1) {
 +        perror("​accept() call failed"​);​
 +        exit(-1);
 +      }
 +      printf("​new connection %s:%d (fd=%d)\n",​ inet_ntoa(remote_addr.sin_addr),​ ntohs(remote_addr.sin_port),​ new_client);​
 +      FD_SET(new_client,​ &​readfds);​
 +      max_fd = (max_fd < new_client) ? new_client : max_fd;
 +      FD_CLR(server,​ &​tmpfds);​
 +    }
 +
 +    int fd;
 +    for(fd=0; fd<​=max_fd;​ ++fd) {
 +      if(FD_ISSET(fd,​ &​tmpfds)) {
 +        len = recv(fd, buffer, 1500, 0);
 +        if(len <= 0) {
 +          if(len < 0) perror("​recv() call failed"​);​
 +          else fprintf(stderr,​ "​client closed connection\n"​);​
 +          ​
 +          printf("​removing client (fd=%d)\n",​ fd);
 +          FD_CLR(fd, &​readfds);​
 +          close(fd);
 +        }
 +        else
 +          printf("​Received %d Bytes from client (fd=%d)\n",​ len, fd);
 +      }
 +    }
 +  }
 +
 +  close(server);​
 +  ​
 +  printf("​exiting TCP Server\n"​);​
 +
 +  return 0;
 +}
 +</​file>​
  
  
realraum Graz, Brockmanngasse 15, 8010 Graz, realraum - Verein für Technik in Kultur und Gesellschaft
  • /var/lib/dokuwiki/data/attic/workshop/sockets.1285782613.txt.gz
  • Last modified: 2010-09-29 19:50
  • by equinox