Heute haben wir uns im Praktikum mit der Entwicklung eines einfachen Systems, bestehend aus einem Server und einem Client, der die Systemzeit des Servers anfragt, beschäftigt. Dabei setzen wir UDP als verbindungsloses Netzwerkprotokoll ein.
| Skript-Anfang | Praktikum_1 – Seite 1 |
|---|---|
| Skript-Ende | Praktikum_1 – Seite 2 |
Aufgabenstellung
Programmieren Sie einen Client und einen Server. Der Client soll mittels UDP vom Server die aktuelle Uhrzeit übermittelt bekommen. Der Client soll dafür eine geeignete Anfrage an den Server schicken und die aktuelle Systemzeit des Servers als Antwort bekommen. Der Server soll auf Port 12345 auf Anfragen warten und jede Anfrage von einem Client mit dessen IP und Port protokollieren. Der Client soll 5 Anfragen nacheinander stellen, jeweils auf die Antwort warten und die Antworten protokollieren.
Erwartete Ausgabe des Clients
[10:35:21] Antwort 1: 10:35:19 [10:35:21] Antwort 2: 10:35:19 [10:35:21] Antwort 3: 10:35:19 [10:35:21] Antwort 4: 10:35:19 [10:35:21] Antwort 5: 10:35:19
Erwartete Ausgabe des Servers
[10:35:19] Anfrage von 192.168.1.102, Port 123 [10:35:19] Anfrage von 192.168.1.102, Port 123 [10:35:19] Anfrage von 192.168.1.102, Port 123 [10:35:19] Anfrage von 192.168.1.102, Port 123 [10:35:19] Anfrage von 192.168.1.102, Port 123
Client
#include <sys/socket.h>
#include <sys/types.h>
#include
#include
#include
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include
#include
int main()
{
//Return value initialisieren
int result = -1;
// Buffer initialisieren
char buf[9];
memset(buf,0,9);
// Variablen für die Zeit
char ctime[9];
time_t current_time;
struct tm * time_info;
memset(ctime,0,9);
// Socket erstellen
int my_socket;
my_socket = socket(AF_INET,SOCK_DGRAM,0);
if (my_socket==-1) {
perror("failed to create UDP socket\n");
return -1;
}
// IP-Adresse und Port des Servers festlegen
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12345);
server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
// Fünf mal Senden
int i=1;
for (i=1; i<6;i++)
{
// Buffer enthält die Sendezeit
time(¤t_time);
time_info = localtime(¤t_time);
strftime(buf, sizeof(buf), "%H:%M:%S", time_info);
// Anfrage an den Server mit Buffer-Daten
result = sendto(my_socket,buf,9,0,(struct sockaddr*)&server_addr,sizeof(server_addr));
if (result<0) {
perror("Senden fehlgeschlagen\n");
return -1;
}
else
{/* printf("Anfrage %d",i);
printf(" an den Server gesendet um ");
printf("%s",buf);
printf("\n");
memset(buf,0,9);*/
}
// Antwort empfangen
result = recvfrom(my_socket,buf,9,0,NULL,NULL);
if (result<0) {
perror("Empfang fehlgeschlagen");
return -1;
}
else
{
time(¤t_time);
time_info = localtime(¤t_time);
strftime(ctime, sizeof(ctime), "%H:%M:%S", time_info);
printf("[%s] Antwort %d: %s\n", ctime, i, buf);
}
// 1/2 Sekunde lang warten
usleep(500000);
}//end for
return result;
}
Server
#include <sys/socket.h>
#include <sys/types.h>
#include
#include
#include
#include <net/if.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include
int main()
{
// Return Value initialisieren
int result = -1;
// Buffer initialisieren
char buf[9];
memset(buf,0,9);
// Socket vom Server setzen
int my_socket;
int optval = 1;
my_socket = socket(AF_INET,SOCK_DGRAM,0);
if (my_socket<0) {
perror("failed to create UDP socket\n");
return -1;
}
result = setsockopt(my_socket,SOL_SOCKET,SO_REUSEADDR,&optval,sizeof(optval));
if (result<0) {
perror("Option REUSEADDR konnte nicht gesetzt werden");
return -1;
}
// Adresse des Servers
struct sockaddr_in server_addr;
server_addr.sin_family = AF_INET;
server_addr.sin_port = htons(12345); // ggfs aendern! Port des Servers
server_addr.sin_addr.s_addr = INADDR_ANY;
// Variablen für die Adresse des Clients initialisieren
struct sockaddr_in client_addr;
client_addr.sin_family = AF_INET;
int client_len = sizeof(client_addr);
int client_port = 0;
char client_ip[INET_ADDRSTRLEN];
// Variablen für die Systemzeit initialisieren
time_t current_time;
struct tm * time_info;
char timeString[9];
// Socket an Server Adresse und Port binden
result = bind(my_socket,(struct sockaddr*)&server_addr,sizeof(struct sockaddr_in));
if (result<0) {
perror("bind fehlgeschlagen");
return -1;
}
// Ausgabe für die Konsole
printf("### Warten auf Anfragen ###\n");
// Busy waiting
while (1)
{
// Anfrage empfangen
result = recvfrom(my_socket,buf,9,0,(struct sockaddr*)&client_addr,(socklen_t*)&client_len);
if (result<0) {
perror("Empfang fehlgeschlagen");
return -1;
}
// Daten parsen
client_port = ntohs(client_addr.sin_port);
inet_ntop(AF_INET, &(client_addr.sin_addr), client_ip, INET_ADDRSTRLEN);
time(¤t_time);
time_info = localtime(¤t_time);
strftime(timeString, sizeof(timeString), "%H:%M:%S", time_info);
// Ausgabe auf der Konsole
printf("[%s] Anfrage von %s, Port: %d, gesendet um %s\n",timeString, client_ip, client_port, buf);
memset(buf,0,9);
// Antwort senden
result = sendto(my_socket, timeString, 9, 0, (struct sockaddr *) &client_addr, sizeof(client_addr));
if (result<0) {
perror("Senden fehlgeschlagen\n");
return -1;
}
}//end while
return result;
}