Differences

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

Link to this comparison view

Next revision
Previous revision
workshop:sockets [2010-09-29 19:47]
equinox angelegt
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 ====
 +
 +<​file>​
 +/*
 + ​* ​ udpclient
 + *
 + ​* ​ This is a very basic UDP client example to show the usage of
 + ​* ​ sockets. ​
 + ​*  ​
 + ​* ​ Copyright (C) 2010 Christian Pointner <​equinox@realraum.at>​
 + *
 + ​* ​ udpclient 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.
 + *
 + ​* ​ udpclient 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 udpclient. 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>​
 +
 +int main(int argc, char** argv)
 +{
 +  if(argc <= 2) {
 +    fprintf(stderr,"​too few arguments\n"​);​
 +    exit(1);
 +  }
 +  printf("​starting UDP Client\n"​);​
 +
 +  int sock = socket(AF_INET,​ SOCK_DGRAM, 0);
 +  if(sock < 0) { 
 +    perror("​socket() call failed"​);​
 +    exit(-1);
 +  }
 +    ​
 +  struct sockaddr_in remote_addr;​
 +  int alen, len;
 +  alen = sizeof(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);
 +  }
 +
 +  uint8_t buffer[1500];​
 +  for (;;) {
 +    if((len = read(0, buffer, 1500))==-1) {
 +      perror("​read() call failed"​);​
 +      exit(-1);
 +    }
 +
 +    if((len = sendto(sock,​ buffer, len, 0, (struct sockaddr *)&​remote_addr,​ alen))==-1) {
 +      perror("​sendto() call failed"​);​
 +      exit(-1);
 +    }
 +  }
 +
 +  close(sock);​
 +  ​
 +  printf("​exiting UDP Client\n"​);​
 +
 +  return 0;
 +}
 +</​file>​
 +
 +==== Beispiel: udpserver ====
 +
 +<​file>​
 +/*
 + ​* ​ udpserver
 + *
 + ​* ​ This is a very basic UDP client example to show the usage of
 + ​* ​ sockets. ​
 + ​*  ​
 + ​* ​ Copyright (C) 2010 Christian Pointner <​equinox@realraum.at>​
 + *
 + ​* ​ udpserver 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.
 + *
 + ​* ​ udpserver 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 udpserver. 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>​
 +
 +int main(int argc, char** argv)
 +{
 +  printf("​starting UDP Server\n"​);​
 +
 +  int sock = socket(AF_INET,​ SOCK_DGRAM, 0);
 +  if(sock < 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(sock,​ (struct sockaddr *)&​local_addr,​ sizeof(local_addr))==-1) { 
 +    perror("​bind() call failed"​);​
 +    exit(-1);
 +  }
 +
 +  struct sockaddr_in remote_addr;​
 +  int alen, len;
 +  alen = sizeof(remote_addr);​
 +  uint8_t buffer[1500];​
 +  for (;;) {
 +    if((len = recvfrom(sock,​ buffer, 1500, 0, (struct sockaddr *)&​remote_addr,​ &​alen))==-1) {
 +      perror("​recvfrom() call failed"​);​
 +      exit(-1);
 +    }
 +
 +    printf("​Received %d Bytes from %s:​%d\n",​ len, inet_ntoa(remote_addr.sin_addr),​ ntohs(remote_addr.sin_port));​
 +  }
 +
 +  close(sock);​
 +  ​
 +  printf("​exiting UDP Server\n"​);​
 +
 +  return 0;
 +}
 +</​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/>​.
 + */
 +
 +#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>​
 +/*
 + ​* ​ 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>​
 +
  
 ---- ----
 {{tag>​workshop}} {{tag>​workshop}}
  
realraum Graz, Brockmanngasse 15, 8010 Graz, realraum - Verein für Technik in Kultur und Gesellschaft
  • /var/lib/dokuwiki/data/attic/workshop/sockets.1285782422.txt.gz
  • Last modified: 2010-09-29 19:47
  • by equinox