Hallo ICH BRAUCHE Dringend Hilfe. Ich hab folgende Programm Server:
C
#include <alloca.h>
#include <assert.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include "hl_common.h"
int main(int argc, char** argv) {
// Turn off output buffering so that we see all messages immediately
if (setvbuf(stdout, NULL, _IONBF, 0) != 0) {
perror("setvbuf failed!");
return 1;
}
int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP); // 6 für IPv6 hinzufügen
if (sock == -1) {
perror("Cannot create socket");
return 1;
}
struct sockaddr_in6 sa; // 6 für IPv6 hinzufügen
memset(&sa, 0, sizeof sa);
sa.sin6_family = AF_INET6;// 6 für IPv6 hinzufügen
sa.sin6_addr = in6addr_any;// 6 für IPv6 hinzufügen
sa.sin6_port = htons(PORT);// 6 für IPv6 hinzufügen
if (bind(sock, (struct sockaddr *) &sa, sizeof sa) == -1) {
perror("bind failed!");
close(sock);
return 1;
}
for (;;) {
struct sockaddr_in6 peer;// 6 für IPv6 hinzufügen
socklen_t peer_len = sizeof peer;
char incoming[1+MAXSIZE];
ssize_t len = recvfrom(sock, incoming, sizeof incoming, 0, (struct sockaddr *) &peer, &peer_len);
if (len == -1) {
perror("recvfrom failed");
break;
}
char peeraddr[sizeof peer];// 6 für IPv6 hinzufügen und inet_ntoa
inet_ntop(AF_INET6, &peer.sin6_addr, peeraddr, sizeof(peeraddr)); //durch inet_ntop erstezen (durch parameterzugabe wird auf char von Zeile 43 zugegriffen)
assert(strlen(peeraddr) < MAXSIZE);
if (len <= 1) {
printf("Message from %s too short\n", peeraddr);
continue;
}
if (incoming[0] != 'M') {
printf("Weird first byte in message from %s: %i\n", peeraddr, (int) incoming[0]);
continue;
}
incoming[len-1] = '\0'; // Ensure that input is a valid C string
// Craft message contents
char* peername = incoming+1;
const char* hostname = get_hostname();
char msg[1+17+3*(MAXSIZE-1)+1];
size_t msglen = snprintf(msg, sizeof msg, "RHello %s (%s)! I am %s.", peername, peeraddr, hostname);
printf("Sending \"%s\" to %s\n", msg, peeraddr);
// Send response message
if (sendto(sock, msg, msglen+1, 0, (struct sockaddr*) &peer, peer_len) == -1) {
perror("Send failed");
break;
}
}
// An error occured
close(sock);
return 2;
}
Alles anzeigen
Client:
C
#include <errno.h>
#include <netdb.h>
#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>
#include "hl_common.h"
void contact(char* host) {
// ermitteln der adresse
struct addrinfo tip, *ergebnis;
memset(&tip, 0, sizeof tip);
memset(&ergebnis, 0, sizeof *ergebnis);
tip.ai_family = AF_UNSPEC; // erlauben von IPv4 oder IPv6
tip.ai_socktype = SOCK_DGRAM; // Datagram socket
tip.ai_flags = 0; // Flags
tip.ai_protocol = 0; // Jedes Protokol
const char *service = "2673";
if (getaddrinfo(host, service, &tip, &ergebnis) != 0) { //von vorheriger aufgabe getaddrinfo
printf("getaddrinfo failed\n");
return;
}
// Create socket
int sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);// 6 für IPv6 hinzufügen
if (sock == -1) {
perror("socket creation failed");
return;
}
// Compose message
char sendbuf[1+MAXSIZE];
int msglen = snprintf(sendbuf, sizeof sendbuf, "M%s", get_hostname()) + 1;
// Configure socket timeouts
struct timeval timeout;
memset(&timeout, 0, sizeof timeout);
timeout.tv_sec = 1;
if (setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout) == -1) {
perror("setsockopt(SO_RCVTIMEO) failed");
close(sock);
return;
}
if (setsockopt(sock, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof timeout) == -1) {
perror("setsockopt(SO_SNDTIMEO) failed");
close(sock);
return;
}
// Send message
if (sendto(sock, sendbuf, msglen, 0, ergebnis->ai_addr, ergebnis->ai_addrlen) == -1) {
perror("sendto failed");
close(sock);
return;
}
char recvbuf[4*MAXSIZE];
struct sockaddr_in6 peer; // 6 für IPv6 hinzufügen
socklen_t peer_len = sizeof peer;
size_t msgsize = recvfrom(sock, &recvbuf, sizeof recvbuf, 0, (struct sockaddr*) &peer, &peer_len);
if (msgsize == -1) {
if (errno == EWOULDBLOCK) {
fprintf(stderr, "No response from %s!\n", host);
close(sock);
return;
}
perror("recvfrom failed");
close(sock);
return;
}
recvbuf[msgsize-1] = '\0';
char peeraddr[INET6_ADDRSTRLEN]; // 6 für IPv6 hinzufügen und
inet_ntop(AF_INET6, &peer,peeraddr, INET6_ADDRSTRLEN); //inet_ntoa durch inet_ntop
if (recvbuf[0] != 'R') {
fprintf(stderr, "Reply from %s(%s) does not follow protocol!\n"
"Expected message type 'R', but got %c\n",
peeraddr, host, recvbuf[0]);
close(sock);
return;
}
printf("\"%s\" from %s (%s)\n", recvbuf+1, peeraddr, host);
close(sock);
}
int main(int argc, char** argv) {
if (argc == 1) {
fprintf(stderr, "No remote host given!\n");
printf("Usage: %s server-ip [server-ip..]\n", argv[0]);
return 1;
}
char** host = argv+1;
while (argc > 1) {
contact(*host);
host++;
argc--;
}
return 0;
}
Alles anzeigen
Jetzt zeigt er aber das falsche bei der ausgabe an.
Ausgabe:
> > > $ ./hl_client ::1 127.0.0.1
> > > "Hello t4 :1)! I am t4." from a00:a71:: :1)
> > > "Hello t4 :ffff:127.0.0.1)! I am t4." from a00:a71:: (127.0.0.1)
Statt a00:a71:: soll da was anderes stehen.
Folgendes habe ich als Erklärung bekommen, kann es jedoch nicht umsetzten.
> > > Das ist etwas fies, weil inet_ntop keine Typüberprüfung für das zweite
> > > Argument vornimmt. Da muss ein Pointer auf ein struct in6_addr
> > > reingegeben
> > > werden.
Kann mir jemand sagen welche Zeile ich wie ändern muss?
Ich bedanke mich schon mal!
Grüße Eraseus