====== Vortrag/Workshop Einführung in Unix Socket Programmierung ====== * 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 ==== /* * udpclient * * This is a very basic UDP client example to show the usage of * sockets. * * Copyright (C) 2010 Christian Pointner * * 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 . */ #include #include #include #include #include #include #include #include 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; } ==== Beispiel: udpserver ==== /* * udpserver * * This is a very basic UDP client example to show the usage of * sockets. * * Copyright (C) 2010 Christian Pointner * * 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 . */ #include #include #include #include #include #include #include #include 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; } ==== Beispiel: tcpclient ==== /* * tcpclient * * This is a very basic TCP client example to show the usage of * sockets. * * Copyright (C) 2010 Christian Pointner * * 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 . */ #include #include #include #include #include #include #include #include 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; } ==== Beispiel: tcpserver ==== /* * tcpserver * * This is a very basic TCP server example to show the usage of * sockets. * * Copyright (C) 2010 Christian Pointner * * 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 . */ #include #include #include #include #include #include #include #include #include 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; } ---- {{tag>workshop}}