====== 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}}