Entwickler/User−Space TCP/IP Stack Verteilte Systeme Übung 4 Alexander Ploß Web−Browser, E−Mail,. Anwendung Andere Anwendungen (erfordern spezielle Optimierung) Appl.−Protokolle: FTP, HTTP, SMTP, ... Andere Anwendungen Middleware: CORBA, RMI Programming Interface (Sockets) Gruppe PVS (Parallele und Verteilte Systeme) Institut für Informatik Westfälische Wilhelms-Universität Münster Betriebssystem TCP Sommersemester 2008 IGMP ICMP RARP ARP UDP Transport RIP IP OSPF Vermittlung Ethernet WLAN ... ATM Netzzugang 4-2 Aufgabe 1: Korrektur für 64bit Systeme 4.1 Aufgabe 1 Vorgabe: Protokoll des Dateidienstes /∗ Service−Schleife ∗/ while (1) { int connsocket, retval; clientrequest req; size_t claddr_size; [..] /∗ blockierend auf eingehende Verbindung warten ∗/ connsocket = accept (listensocket, (struct sockaddr ∗) &claddr, &claddr_size); size_t Client-Anfragen: Client-Anforderung Datei empfangen (GET) Zusatz Dateiname Server-Antworten: ist hier laut man 2 accept nicht korrekt: int accept(int sockfd, struct sockaddr ∗addr, socklen_t ∗addrlen); Das Führt auf 64bit Systemen leider zu einem Fehler Korrektur: Server-Antwort Datei übermitteln (OK) Datei nicht gefunden (NOT FOUND) Ungültige Anfrage (BAD REQUEST) Zusatz Dateilänge und Dateiinhalt - Mögliche Erweiterungen: Client-Anforderung Verzeichnisinhalt anzeigen (LIST) Datei löschen (DEL) Datei übermitteln (PUT) /∗ Service−Schleife ∗/ while (1) { int connsocket, retval; clientrequest req; socklen_t claddr_size; [..] 4-3 Zusatz Dateiname Dateiname, Dateigröße, Dateiinhalt 4-4 4.1 Aufgabe 1 4.1 Aufgabe 1 Datenstrukturen des Protokolls (fileprotocol.h) Datentyp Client-Anfrage Mögliche Client-Anfragen typedef struct { int reqlen; int cmd; /∗ file_clientcommand ∗/ char filename[FP_MAXFILENAME]; } clientrequest; enum file_clientcommand { FP_GET }; Mögliche Server-Antworten Datentyp Server-Antwort (statischer Teil) enum file_serverretcode { FP_OK = 0, FP_BADREQUEST, FP_FILENOTFOUND, FP_GENERROR }; typedef struct { int retcode; /∗ file_serverretcode ∗/ int filelen; } serverresponse; 4-5 4.1 Aufgabe 1 4-6 4.1 Aufgabe 1 Versenden der Client-Anfrage (fileclient.c) Generische sendMsg-Funktion /∗ Request an Server ueber sock senden ∗/ int send_request(int ∗sock, char ∗filename) { clientrequest req; [...] /∗ Sendet &len Bytes beginnend bei msg ueber sock, Gibt −1 bei Fehler und 0 bei Erfolg zurueck, Tatsächliche Anzahl gesendeter Bytes wird in len geschrieben ∗/ int sendMsg(int sock, char ∗msg, int ∗len) { int total = 0; int bytesleft = ∗len; int n; /∗ Request ausfuellen ∗/ req.cmd = FP_GET; req.cmd = htonl(req.cmd); strncpy(req.filename, filename, FP_MAXFILENAME); /∗ Nachricht senden ∗/ sendMsgSize = sizeof(req); retval = sendMsg(∗sock, (char∗)&req, &sendMsgSize); /∗Fehlerbehandlung entsprechend retval∗/ while(total < ∗len) { n = send(sock, msg + total, bytesleft, 0); if (n == −1) { break; } total += n; bytesleft −= n; } } Das direkte Versenden des struct clientrequest ist problematisch, Größe und Alignment kann auf verschiedenen Architekturen unterschiedlich sein! ⇒ Eigenes Marshalling/Unmarshalling: clreq_to_char und char_to_clreq-Funktionen implementieren ∗len = total; return n==−1?−1:0; } 4-7 4-8 4.1 Aufgabe 1 4.1 Aufgabe 1 Empfang der Server-Antwort (fileclient.c) /∗ Datei empfangen und ausgeben ∗/ if(resp.retcode == FP_OK) { while(filerecvd < resp.filelen) { bytesrcvd = recv(∗sock, buffer, BUFSIZE−1, 0); if(bytesrcvd <= 0) { fprintf (stderr, "receiving file failed\n"); return −1; } buffer[bytesrcvd] = ’\0’; fprintf (stdout, "%s", buffer); filerecvd += bytesrcvd; } } return 0; /∗ Reply vom Server ueber sock empfangen ∗/ int recv_reply(int ∗sock) { char buffer[BUFSIZE]; serverresponse resp; /∗ Antwort empfangen ∗/ bytesrcvd = recv(∗sock, &resp, sizeof(resp), 0); /∗[..] Fehlerbehandlung entsprechend bytesrcvd∗/ resp.retcode = ntohl(resp.retcode); resp.filelen = ntohl(resp.filelen); if(resp.retcode == FP_BADREQUEST) err("Server responded: FP_BADREQUEST\n"); if(resp.retcode == FP_FILENOTFOUND) err("Server responded: FP_FILENOTFOUND\n"); if(resp.retcode == FP_GENERROR) err("Server responded: FP_GENERROR\n"); } 4-9 Entwickler/User−Space 4.2 TCP/IP-Stack TCP/IP: Transportschicht Web−Browser, E−Mail,. FTP, HTTP, SMTP, ... Aufgabe der Transportschicht: Anwendung Andere Anwendungen Datentransport zwischen Prozessen Andere Anwendungen Zwei Transportprotokolle im TCP/IP-Stack: UDP - User Datagram Protocol (erfordern spezielle Optimierung) Appl.−Protokolle: Middleware: CORBA, RMI Unzuverlässige Kommunikation, kein Verbergen der zugrundeliegenden IP-Unzuverlässigkeiten Protokollentwickler muss selbst Mechanismen zu Erreichen der gewünschten Zuverlässigleit implementieren Programming Interface (Sockets) Betriebssystem TCP IGMP ICMP RARP ARP 4-10 UDP Transport RIP IP TCP - Transmission Control Protocol Expliziter Verbindungsaufbau Erhält Absendereihenfolge von Daten Liefert Daten garantiert aus OSPF Vermittlung Ethernet WLAN ... ATM Welches Protokoll man einsetzt hängt von der Anwendung ab Netzzugang 4-11 4-12 Transportschicht: UDP-Header Transportschicht: TCP-Header 0 1 2 3 4 56 7 8 9 0 12 3 4 5 6 7 89 0 1 2 3 45 6 7 8 901 Quell−Port Ziel−Port Sequenznummer 012 345 678 9 01 2345 678 901 2345 678 901 Quell−Port Bestätigungsnummer Ziel−Port Länge Offset nicht verw. Prüfsumme 1 2 3 4 5 6 Prüfsumme Fenster Dringlich Optionen Daten . . . Füllbytes Daten . . . 1 URG 2 ACK 3 PSH 4 RST 5 SYN 6 FIN 4-13 Transportschicht: TCP-Zustandsautomat 4-14 Transportschicht: TCP-Verbindungsaufbau CLOSED 3-way handshake“: ” EINGABE/AUSGABE (Anwendungsbefehlle) (passive open)/ (active open)/SYN timeout/RST LISTEN SYN/SYN,ACK (active open) (send data)/SYN RST/ ESTABLISHED (close)/FIN SYN SENT timeout SYN,ACK/ACK ACK/ SEQ=100 CTL=SYN CLOSED FIN WAIT−2 FIN,ACK/ACK FIN/ACK DATA LISTEN SYN−RECVD ESTABLISHED (passive open) CLOSING LAST ACK ACK/ SEQ=101 ACK=301 CTL=ACK CLOSE WAIT (close)/FIN FIN WAIT−1 SEQ=300 ACK=101 CTL=SYN,ACK FIN/ACK (close)/FIN FIN/ACK ESTABLISHED (close) SYN/SYN,ACK SYN RECVD SYN−SENT CLOSED ACK/ ACK/ TIME WAIT timeout 4-15 4-16