Socket Application Programming Interface

Σχετικά έγγραφα
Ζητήματα Σχεδίασης Λογισμικού Πελάτη

Προγραμματισμός με BSD Sockets σε περιβάλλον Linux

Ντίρλης Νικόλαος- ΕΤΥ 3ο ΦΡΟΝΤΙΣΤΗΡΙΟ ΠΑΡΑΣΚΕΥΗ 25 ΟΚΤΩΒΡΙΟΥ 2013 ΑΙΘΟΥΣΑ Β4

Δίκτυα Επικοινωνιών ΙΙ: Network Programming TCP Sockets

Εργαστήριο Δικτύων Υπολογιστών

Δικτυακός Προγραμματισμός (Sockets Programming) Εργαστήριο Γ Εξάμηνο, Τμήμα Πληροφορικής Πανεπιστήμιο Θεσσαλίας

Λειτουργικά Συστήματα

ΗY335: Δίκτυα Υπολογιστών Χειμερινό Εξάμηνο Τμήμα Επιστήμης Υπολογιστών Πανεπιστήμιο Κρήτης Διδάσκουσα: Μαρία Παπαδοπούλη

ΟΙΚΟΝΟΜΙΚΟ ΠΑΝΕΠΙΣΤΗΜΙΟ ΑΘΗΝΩΝ ΤΜΗΜΑ ΠΛΗΡΟΦΟΡΙΚΗΣ

Ζητήματα Σχεδίασης Λογισμικού Εξυπηρετητή

Δίκτυα Επικοινωνιών ΙΙ: Network Programming UDP Sockets, Signals

Υποδοχείς (Sockets) Προγραμματισμός II 1

Εργαστήριο Λειτουργικών Συστήματων 8ο εξάμηνο, Ακαδημαϊκή περίοδος

Πρωτόκολλο FTP. Από τα παλαιότερα πρωτόκολλα του ArpaNet Το FTP είναι μια τυποποίηση του TCP/IP Πρόκειται για πρωτόκολο γενικού σκοπού

Δικτυακός προγραμματισμός

Επικοινωνία Client/Server Υποδοχές

Εγχειρίδιο Συναρτήσεων. Socket *sopen(const int type, const int protocol, const char *host, const char *service)

Επίπεδο Μεταφοράς. (ανεβαίνουμε προς τα πάνω) Εργαστήριο Δικτύων Υπολογιστών Τμήμα Μηχανικών Η/Υ και Πληροφορικής

{ int pipe(int fd[ ]) close

2η Προγραµµατιστική Εργασία

(C) 2010 Pearson Education, Inc. All rights reserved.

Web and HTTP. Βασικά Συστατικά: Web Server Web Browser HTTP Protocol

Επικοινωνία Client/Server Απομακρυσμένη Κλήση Διαδικασιών

ιαδικτυακές Εφαρµογές

Σύντομη παρουσίαση των εργαλείων/εντολών telnet, ping, traceroute nslookup και nmap, zenmap

Δίκτυα Υπολογιστών ΙΙ (Ασκήσεις Πράξης)

4 η ιάλεξη: Signals UDP Sockets

CloudBox!: Ένα εργαλείο cloud αποθήκευσης αρχείων με κατανεμημένο τρόπο

ΑΤΜ PROJECT ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ Άννα Τριανταφύλλου ΑΕΜ : 456. επιβλέπων καθηγητής: Μηνάς Δασυγένης

Επίπεδο δικτύου IP Forwading κτλ

Ειδικά Θέματα Προγραμματισμού

Μετατροπή χαρακτήρων ASCII σε αριθμό (atoi) & διάβασμα, και αποθήκευση του περιεχομένου του στη μνήμη. (Διάλεξη. Πανεπιστήμιο Κύπρου

HY335 4ο Φροντιστήριο

Κεφάλαιο 7 Διαδικτύωση-Internet. 7.2 Τεχνολογία TCP/IP

Δίκτυα Η/Υ στην Επιχείρηση

Εργαστήριο Δικτύων Υπολογιστών

Μετατροπή χαρακτήρων ASCII σε ακέραιο αριθµό (atoi) & Άνοιγµα αρχείου µέσα από τo QtSPIM, διάβασµα, και αποθήκευση του περιεχοµένου του στη µνήµη

Διδάσκων: Παναγιώτης Ανδρέου

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ

Προγραμματισμός Ι. Δυναμική Διαχείριση Μνήμης. Δημήτρης Μιχαήλ. Ακ. Έτος Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Δίκτυα Υπολογιστών Firewalls. Χάρης Μανιφάβας

Επικοινωνία Διεργασιών στο Internet με POSIX Sockets

Προγραµµατισµός ικτύων Ε-01

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ

Η γλώσσα προγραμματισμού C

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

Βασικά Θέματα Επικοινωνίας. Κατανεμημένα Συστήματα 1

Εργαστήριο Λειτουργικών Συστημάτων 8o εξάμηνο, Ροή Υ, ΗΜΜΥ

Topic 5: Sockets. *Ευχαριστίες στους Jim Kurose, Keith Ross, Τάκη Σταµατόπουλο, Αλέξη ελή, και Αντώνη ελιγιαννάκη

Προγραμματισμός Ι. Προεπεξεργαστής. Δημήτρης Μιχαήλ. Τμήμα Πληροφορικής και Τηλεματικής Χαροκόπειο Πανεπιστήμιο

Προγραμματισμός συστημάτων UNIX/POSIX

Η Υλοποίηση της Επικοινωνίας. Κατανεµηµένα Συστήµατα

HY-335a Project: microtcp *, μία lightweight TCP βιβλιοθήκη

Εξοικείωση με τις εντολές ipconfig και ping

Δημιουργία & Τερματισμός Διεργασιών. Προγραμματισμός II 1

ΜΕΤΑΦΟΡΑ ΑΡΧΕΙΩΝ FTP

Προγραµµατισµός ικτύων Ε-01

ικτύωσησε Java Κατανεµηµένα Συστήµατα 08-1

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

#include <stdlib.h> Α. [-128,127] Β. [-127,128] Γ. [-128,128]

ΤΕΧΝΟΛΟΓΙΑ ΙΚΤΥΩΝ ΕΠΙΚΟΙΝΩΝΙΩΝ

Διαχείριση Δικτύων Εργαστήριο (Διαφάνειες)

ΚΕΦΑΛΑΙΟ 10. Δικτυακός προγραμματισμός Εισαγωγή

Κ. Στάµος Μηχανικός Η/Υ και Πληροφορικής, Πανεπιστήµιο Πατρών Μηχανικός Έρευνας και Ανάπτυξης, ΕΜ6/ΕΑΙΤΥ

ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΣ Η/Υ Ακαδημαϊκό έτος ΤΕΤΡΑΔΙΟ ΕΡΓΑΣΤΗΡΙΟΥ #4

Βιβλιοθήκη stdio. Προγραμματισμός II 1

Εισαγωγή στον Προγραμματισμό

Κεφάλαιο 7.3. Πρωτόκολλο TCP

Εικονική Μνήμη (Virtual Memory) Προγραμματισμός II 1

Φροντιςτήριο. Linked-List

ΗΜΥ 213 Εργαστήριο Οργάνωσης Ηλεκτρονικών Υπολογιστών και Μικροεπεξεργαστών

ΗΜΥ 213 Εργαστήριο Οργάνωσης Ηλεκτρονικών Υπολογιστών και Μικροεπεξεργαστών

Εργαστήριο 9: Αρχεία

ΗΜΥ 213 Εργαστήριο Οργάνωσης Ηλεκτρονικών Υπολογιστών και Μικροεπεξεργαστών

50 Ketseo,Theoni Sarif,Omar 104

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ. Διεργασίες και Νήματα Εργαστηριακές Ασκήσεις

Δομημένος Προγραμματισμός (ΤΛ1006)

Δομημένος Προγραμματισμός. Τμήμα Επιχειρηματικού Σχεδιασμού και Πληροφοριακών Συστημάτων

Πρωτόκολλα Διαδικτύου

Ιόνιο Πανεπιστήμιο Τμήμα Πληροφορικής Εισαγωγή στην Επιστήμη των Υπολογιστών Δίκτυα υπολογιστών. (και το Διαδίκτυο)

(Κεφάλαιο 2.7 και 12) Αρχεία στην C. (Διάλεξη 15)

ΕΡΓΑΣΤΗΡΙΟ 9: Συμβολοσειρές και Ορίσματα Γραμμής Εντολής

Network Address Translation (NAT)

Προγραμματισμός συστημάτων UNIX/POSIX. Διαδιεργασιακή επικοινωνία: αγωγοί (IPC inter-process communication: pipes)

Προγραμματισμός Ι (ΗΥ120)

Βασικές Υπηρεσίες Διαδικτύου. Επικοινωνίες Δεδομένων Μάθημα 2 ο

Προγραμματισμός Η/Υ (ΤΛ2007 )

ΚΑΤΑΝΕΜΗΜΕΝΑ ΣΥΣΤΗΜΑΤΑ. Παράδοση Ασκήσεων Κεφάλαιο 2 Ασκήσεις 3,6,8,9,15,22,24,26. Γεωργόπουλος Άλκης Α.Μ.: 39 Κοντογιώργης Αναστάσιος A.M.

PROXY SERVER. Άριστη πύλη διαχωρισμού μεταξύ του εσωτερικού δικτύου και του Internet.

Α2. Να γράψετε τους αριθμούς 1-5 από τη Στήλη Α και δίπλα το γράμμα της Στήλης Β που δίνει τη σωστή αντιστοίχηση.

14. Δικτύωση με Java Δικτύωση με Java Sockets Δημιουργία της σύνδεσης Διευθυνσιοδότηση της σύνδεσης

ΕΑΠ/ΠΛΗ22/ΑΘΗ.3 4 η ΟΣΣ 15/03/2014 Συμπληρωματικές Διαφάνειες

Πρωτόκολλα Επικοινωνίας Πρωτόκολλο IP

ΤΕΧΝΟΛΟΓΙΑ ΔΙΚΤΥΩΝ ΕΠΙΚΟΙΝΩΝΙΩΝ 7ο ΚΕΦΑΛΑΙΟ

7.2.2 Σχέση OSI και TCP/IP

Επεξεργασία Αρχείων Κειµένου

ΚΥΠΡΙΑΚΗ ΕΤΑΙΡΕΙΑ ΠΛΗΡΟΦΟΡΙΚΗΣ CYPRUS COMPUTER SOCIETY ΠΑΓΚΥΠΡΙΟΣ ΜΑΘΗΤΙΚΟΣ ΔΙΑΓΩΝΙΣΜΟΣ ΠΛΗΡΟΦΟΡΙΚΗΣ 24/3/2007

ΛΕΙΤΟΥΡΓΙΚΑ ΣΥΣΤΗΜΑΤΑ II. Υφαντόπουλος Νικόλαος Υποψήφιος Διδάκτορας Contact:

Δίκτυα Υπολογιστών. Το επίπεδο εφαρμογής (application layer) Κ. Βασιλάκης

Συμβολοσειρές Ορίσματα στη main()

Transcript:

Socket Application Programming Interface

Εισαγωγή Το socket είναι ένας τύπος διεπαφής μεταξύ των προγραμμάτων εφαρμογής και του λογισμικού πρωτοκόλλων Είναι ευρέως διαθέσιμο για να διασφαλίζεται η μεταφερσιμότητα των προγραμμάτων Χρησιμοποιείται από πελάτες και εξυπηρετητές Αποτελεί μια προέκταση του μηχανισμού αρχείων Ι/Ο του UNIX

API Οι αλληλεπιδράσεις των εφαρμογών με το λογισμικό πρωτοκόλλων περιλαμβάνουν: παθητική ακρόαση ή ενεργοποίηση σύνδεσης πρωτόκολλο που θα χρησιμοποιηθεί διεύθυνση IP και αριθμός πόρτας Η διεπαφή προς το λογισμικό πρωτοκόλλων ονομάζεται Application Program Interface (API) Ορίζεται προγραμματιστικά ή από το λειτουργικό σύστημα περιλαμβάνει μια συλλογή από διαδικασίες προσπελάσιμες από το πρόγραμμα εφαρμογής

Το Socket API Τα πρωτόκολλα δεν προσδιορίζουν το API To API ορίζεται προγραμματιστικά Επιτρέπει συμβατότητα εφαρμογών σε διαφορετικά υπολογιστικά συστήματα Το socket API αρχικά δημιουργήθηκε στο Berkeley BSD UNIX διαθέσιμο στα Windows, linux, etc. Προσοχή: Δεν ορίζεται σαν κάποια επιπλέον τυποποίηση του TCP/IP

Sockets και βιβλιοθήκες sockets Το BSD UNIX υλοποιεί το socket API σαν κλήσεις του λειτουργικού συστήματος Άλλοι κατασκευαστές (κυρίως UNIX συστημάτων) ακολούθησαν την ίδια λογική Διαφορετικά συστήματα έχουν διαφορετικές υλοποιήσεις 1. προσθέτοντας τα sockets σε υπάρχον λειτουργικό σύστημα απαιτεί προφανώς την αλλαγή του ΛΣ ή 2. νέες ρουτίνες βιβλιοθήκης υλοποιούν τα sockets Προστίθεται έτσι ένα επιπλέον επίπεδο λογισμικού μεταξύ των εφαρμογών και του λειτουργικού συστήματος το οποίο αυξάνει τη μεταφερσιμότητα των εφαρμογών αποκρύπτει την πραγματική υλοποίηση της διεπαφής με τα πρωτόκολλα δηλαδή το πραγματικό API

Sockets και βιβλιοθήκες sockets (2)

Sockets και UNIX I/O Τα sockets αναπτύχθηκαν σαν μια προέκταση του συστήματος εισόδου/εξόδου I/O του UNIX Χρησιμοποιούν το ίδιο σύνολο descriptor αρχείων (μικροί ακέραιοι αριθμοί) Βασίζονται στη λογική open-read-write-close open - προετοίμασε ένα αρχείο/συσκευή για πρόσβαση read/write - διάβασε/γράψε τα περιεχόμενα του αρχείου close - τερμάτισε τη χρήση του αρχείου H κλήση οpen επιστρέφει ένα file descriptor, ο οποίος χρησιμοποιείται για να προσδιορίζει το αρχείο στο διάβασμα/γράψιμο/κλείσιμο

Το Socket API O προγραμματισμός sockets είναι πολυπλοκότερος από τη διαχείριση αρχείων I/O Απαιτεί περισσότερες παραμέτρους διευθύνσεις IP αριθμοί πορτών πρωτοκόλλων τύποι πρωτοκόλλων Δύο δυνατές προσεγγίσεις Πρόσθεση νέων παραμέτρων σε υφιστάμενες κλήσεις του συστήματος για Ι/Ο Δημιουργία νέων κλήσεων συστήματος Τα sockets χρησιμοποιούν ένα νέο σύνολο κλήσεων

Περίληψη των socket system calls socket - δημιουργία ενός νέου socket close - τερματισμός της χρήσης ενός socket bind - σύνδεση μιας δνσης δικτύου και ενός socket listen - αναμονή για εισερχόμενα μηνύματα accept - αποδοχή και έναρξη χρήσης εισερχόμενης σύνδεσης connect - επιχείρηση σύνδεσης σε απομακρυσμένο Η/Υ send - αποστολή δεδομένων σε ενεργή σύνδεση recv - λήψη δεδομένων από ενεργή σύνδεση

socket descriptor = socket(protofamily, type, protocol) Επιστρέφει socket descriptor που χρησιμοποιείται σε επόμενες κλήσεις protofamily - επιλέγει την οικογένεια πρωτοκόλλων,πχ: PF_INET - πρωτόκολλα διαδικτύου PF_APPLETALK - πρωτόκολλα AppleTalk type - επιλέγει τον τύπο της επικοινωνίας SOCK_DGRAM - χωρίς σύνδεση SOCK_STREAM - με σύνδεση protocol - προσδιορίζει το πρωτόκολλο μέσα στην οικογένεια πρωτοκόλλων IPPROTO_TCP - επιλέγει το TCP IPPROTO_UDP - επιλέγει το UDP μπορεί ένας τύπος επικοινωνίας να έχει δύο πρωτόκολλα

close close(descriptor) κλείνει τη σύνδεση τερματίζει τη χρήση ενός socket descriptor descriptor - πρόκειται για τον descriptor του socket που θα τερματιστεί

bind bind(socket,localaddr,addresslen) Αρχικά ένα socket στον εξυπηρέτη δεν αντιστοιχεί σε κάποια διεύθυνση (IP addr) και υπηρεσία (port) bind - επιλέγει μια τοπική διεύθυνση στον εξυπηρέτη και την τοπική πόρτα της υπηρεσίας και τις αντιστοιχίζει στο socket

Τύποι διευθύνσεων sockets Επειδή τα sockets μπορούν χρησιμοποιηθούν από διάφορα πρωτόκολλα ο τύπος της δνσης είναι γενικός: struct sockaddr { u_char sa_len; /* total length of address */ u_char sa_family; /* family of the address */ char sa_data[14]; /* address */ } Για τα πρωτόκολλα TCP/IP, το sa_data περιέχει τη δνση IP address και την πόρτα: struct sockaddr_in { u_char sin_len; /* total length of address */ u_char sin_family; /* family of the address */ u_short sin_port; /* protocol port number */ struct in_addr sin_addr; /* IP address */ char sin_zero[8] /* unused */ } Τα πρώτα δύο πεδία ταιριάζουν στη γενική δομή sockaddr Τα υπόλοιπα συναντώνται μόνο στα πρωτόκολλα IP Η σταθερά INADDR_ANY στη θέση της δνσης IP μεταφράζεται σαν οιαδήποτε IP δνση (multihomed Η/Υ)

Δομή sockaddr Δομή sockaddr_in (TCP/IP)

listen listen(socket, queuesize) Ο εξυπηρετητής χρησιμοποιεί τη listen για την αναμονή εισερχομένων συνδέσεων socket - προσδιορίζει το socket μέσω του οποίου θα καταφθάνουν οι αιτήσεις Νέες αιτήσεις μπορεί να καταφθάνουν καθώς ο εξυπηρετητής σερβίρει προηγούμενη αίτηση Το λειτουργικό κρατά τις αιτήσεις σε μια ουρά queuesize - θέτει ένα άνω όριο για τις αναμένουσες αιτήσεις - επιπλέον αιτήσεις χάνονται

accept newsock=accept(sock,caddress,caddresslen) Ο εξυπηρετητής χρησιμοποιεί την accept για να αποδεχθεί την επόμενη αίτηση σύνδεσης Η accept μπλοκάρει σε άδεια ουρά εισερχόμενων αιτήσεων και αναμένει μέχρι να φθάσει μια νέα σύνδεση Επιστρέφει ένα νέο socket που αντιστοιχεί στο νέο ακραίο σημείο πρόσβασης (στον εξυπηρετητή slave αν υπάρχει) της νέας σύνδεσης Το παλαιό socket παραμένει ανέπαφο και ο εξυπηρετητής (master αν υπάρχει) συνεχίζει να ακούει εισερχόμενες κλήσεις σε αυτό caddress - επιστρέφει τη δομή sockaddr με τη διεύθυνση του πελάτη; ο τύπος της δνσης εξαρτάται από την οικογένεια πρωτοκόλλων του socket caddresslen - επιστρέφει το μήκος της δνσης

connect connect(socket, saddress, saddresslen) Ο πελάτης χρησιμοποιεί την connect για να εγκαταστήσει μια σύνδεση με έναν εξυπηρετητή Μπλοκάρει μέχρι η σύνδεση να γίνει αποδεκτή socket - κρατά τον descriptor του socket που θα χρησιμοποιηθεί saddress - δομή sockaddr που προσδιορίζει τον εξυπηρετητή saddresslen - δίνει το μήκος της saddress Η connect συνήθως χρησιμοποιείται σε πρωτόκολλα με σύνδεση Χρησιμοποιείται και σε πρωτόκολλα χωρίς σύνδεση Συνδέει το τοπικό socket με τη δνση του εξυπηρετητή Εμμέσως προσδιορίζει/καταγράφει τον εξυπηρετητή για ενδεχόμενα επόμενα μηνύματα αποστολής σε αυτόν

send send(socket,data,length,flags) Χρησιμοποιείται για την αποστολή δεδομένων σε ένα ήδη συνδεδεμένο socket socket - descriptor που προσδιορίζει το socket data - δείχνει στα δεδομένα προς αποστολή length - το μήκος της περιοχής των δεδομένων (σε bytes) flags - προσδιορίζουν ειδικές επιλογές

Χρησιμοποιείται με μή συνδεδεμένα sockets προσδιορίζοντας ξεκάθαρα τον παραλήπτη destaddress - η δομή sockaddr της δνσης προορισμού addresslen - το μήκος της destaddress sendmsg - συνδυάζει μια λίστα παραμέτρων σε μια μόνο δομή: struct msgstruct { struct sockaddr *m_addr; /*ptr to destination address */ struct datavec *m_vec; /*pointer to message vector */ int m_dvlength; /*num. of items in vector */ struct access *m_rights;/* ptr to access rights list */ int m_alength; /* num. of items in list */ } sendto-sendmsg sendto(socket,data,length,flags,destaddress,addresslen) sendmsg(socket, msgstruct, flags)

recv len=recv(socket,buffer,length,flags) Χρησιμοποιείται για τη λήψη εισερχομενων δεδομένων μέσω κάποιου συνδεδεμένου socket socket - o descriptor που προσδιορίζει το socket Τα δεδομένα αντιγράφονται στην περιοχή που δείχνει ο buffer Το πολύ length bytes θα ληφθούν flags - δίνει ειδικές επιλογές options Επιστρέφει το πλήθος των bytes που πραγματικά ελήφθησαν 0 υπονοεί ότι η σύνδεση έκλεισε (υπονοεί λήψη EOF) -1 υπονοεί κάποιο λάθος

recvfrom - recvmsg recvfrom(socket,buffer,length,flags,sndraddress,addresslen) recvmsg(socket, msgstruct, flags) Οπως οι sendto και sendmsg για μη συνδεδεμένα sockets Η διεύθυνση του αποστολέα αντιγράφεται στη δομή sndraddress Το μήκος της δνσης δίνεται στο addresslen recvmsg - χρησιμοποιεί τη δομή msgstruct για όλες τις παραμέτρους

Χρήση κλήσεων sockets CLIENT SIDE socket connect send recv close SERVER SIDE socket bind listen accept recv send close

Αλλες βοηθητικές ρουτίνες gethostname - πληροφορίες για τον Η/Υ όπου εκτελείται getpeername - δίνει τη δνση του άλλου ακραίου σημείου της σύνδεσης gethostbyname - το DNS μεταφράζει όνομα σε IP δνση gethostbyaddr - το DNS μεταφράζει IP δνση σε όνομα getsockname - δίνει την τρέχουσα δνση που αντιστοιχεί σε κάποιο socket setsockopt - θέτει τις επιλογές για το socket (πχ μέγεθος buffer του πρωτοκόλλου - διαπραγμάτευση εφαρμογών) getsockopt - διαβάζει τις επιλογές για το socket

Διάταξη των bytes στο δίκτυο Σε μια ροή bytes ποιο είναι το πιο σημαντικό και ποιο το λιγότερο σημαντικό; Η διάταξη των οκτάδων στο δίκτυο μπορεί να διαφέρει από τη διάταξή τους σε κάποιο υπολογιστικό σύστημα Στο διαδίκτυο το πιο σημαντικό byte είναι το πρώτο στη σειρά (αυτό που φθάνει πρώτο) Απαιτούνται ρουτίνες μετατροπής ntohs : μετατροπή από network σε host αναπαράσταση μιας τιμής των 2 bytes (htons το αντίστροφο) ntohl : μετατροπή από host σε network αναπαράσταση μιας τιμής των 4 bytes (htonl το αντίστροφο) Προφανώς a=htons(ntohs(a)) και b=htonl(ntohl(b))

Sockets και διαδικασίες Οπως οι file descriptors, έτσι και τα sockets κληρονομούνται από τις διαδικασίες παιδιά Το socket ελευθερώνεται όταν όλες οι διαδικασίες που το έχουν ανοικτό το κλείσουν με close Οι εξυπηρετητές master χρησιμοποιούν την κληρονομικότητα των sockets για να περνούν νέες εισερχόμενες συνδέσεις σε αντίστοιχες διαδικασίες εξυπηρετητών slave

Παράδειγμα πελάτη - εξυπηρετητή

Επικοινωνία με σύνδεση Ο προγραμματιστής client/server εφαρμογών πρέπει να επιλέξει μεταξύ της επικοινωνίας με ή/και χωρίς σύνδεση Το παράδειγμα χρησιμοποιεί υπηρεσία μεταφοράς με σύνδεση Ο εξυπηρετητής καλεί το τοπικό λογισμικό πρωτοκόλλων για να αρχίσει να δέχεται εισερχόμενες συνδέσεις Ο πελάτης εγκαθιστά τη σύνδεση με τον εξυπηρετητή καλώντας το δικό του τοπικό λογισμικό πρωτοκόλλων Η ανταλλαγή δεδομένων γίνεται αφού η εγκατασταθεί σύνδεση

Υπηρεσία παραδείγματος Εξυπηρετητής καταγράφει το πλήθος των επαφών που του έχουν γίνει επιστρέφει τον αριθμό των επαφών σε ένα ASCII string Πελάτης Εγκαθιστά μια σύνδεση Περιμένει για ένα μήνυμα από τον εξυπηρετητή (ASCII string) Τυπώνει τα δεδομένα του μηνύματος Πρωτόκολλο επιπέδου εφαρμογής: Συντακτικό μηνυμάτων (syntax): Χωρίς επικεφαλίδες (επιπέδου εφαρμογής εννοείται) Ο πελάτης στέλνει μήνυμα χωρίς σώμα μηνύματος Το σώμα μηνύματος του εξυπηρέτη περιέχει το ASCII string Σημασιολογία μηνυμάτων (Semantics): ο πελάτης εγκαθιστά σύνδεση και ο εξυπηρετητής επιστρέφει ένα ASCII string

Προγράμματα παραδείγματος Εξυπηρετητής (server.c) Τρέχει σαν πρόγραμμα στο background Δέχεται εναλλακτικά και ένα όρισμα: τον αριθμό της πόρτας στην οποία θα ακούει (η default πόρτα είναι 5193) Πελάτης (client.c) Τρέχει σαν πρόγραμμα χρήστη στο foreground Δέχεται εναλλακτικά δύο ορίσματα: όνομα του Η/Υ που θα κληθεί (η default τιμή είναι localhost) τον αριθμό πόρτας της υπηρεσίας (που ακούει ο εξυπηρετητής)

/* client.c - code for example client program that uses TCP */ #ifndef unix #define WIN32 #include <windows.h> #include <winsock.h> #else #define closesocket close #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #endif #include <stdio.h> #include <string.h> #define PROTOPORT 5193 /* default protocol port number */ extern int errno; char localhost[] = "localhost"; /* default host name */ /*------------------------------------------------------------------------ * Program: client * * Purpose: allocate a socket, connect to a server, and print all output * * Syntax: client [ host [port] ] * * host - name of a computer on which server is executing * port - protocol port number server is using * * Note: Both arguments are optional. If no host name is specified, * the client uses "localhost"; if no protocol port is * specified, the client uses the default given by PROTOPORT. * *------------------------------------------------------------------------ */

main(argc, argv) int argc; char *argv[]; { struct hostent *ptrh; /* pointer to a host table entry */ struct protoent *ptrp; /* pointer to a protocol table entry */ struct sockaddr_in sad; /* structure to hold an IP address */ int sd; /* socket descriptor */ int port; /* protocol port number */ char *host; /* pointer to host name */ int n; /* number of characters read */ char buf[1000]; /* buffer for data from the server */ #ifdef WIN32 WSADATA wsadata; WSAStartup(0x0101, &wsadata); #endif memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */ sad.sin_family = AF_INET; /* set family to Internet */ /* Check command-line argument for protocol port and extract */ /* port number if one is specified. Otherwise, use the default */ /* port value given by constant PROTOPORT */ if (argc > 2) { /* if protocol port specified */ port = atoi(argv[2]); /* convert to binary */

} else { port = PROTOPORT; /* use default port number */ } if (port > 0) /* test for legal value */ sad.sin_port = htons((u_short)port); else { /* print error message and exit */ fprintf(stderr,"bad port number %s\n",argv[2]); exit(1); } /* Check host argument and assign host name. */ if (argc > 1) { host = argv[1]; /* if host argument specified */ } else { host = localhost; } /* Convert host name to equivalent IP address and copy to sad. */ ptrh = gethostbyname(host); if ( ((char *)ptrh) == NULL ) { fprintf(stderr,"invalid host: %s\n", host); exit(1); } memcpy(&sad.sin_addr, ptrh->h_addr, ptrh->h_length); /* Map TCP transport protocol name to protocol number. */ if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) { fprintf(stderr, "cannot map \"tcp\" to protocol number"); exit(1); }

/* Create a socket. */ sd = socket(pf_inet, SOCK_STREAM, ptrp->p_proto); if (sd < 0) { fprintf(stderr, "socket creation failed\n"); exit(1); } /* Connect the socket to the specified server. */ if (connect(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) { fprintf(stderr,"connect failed\n"); exit(1); } /* Repeatedly read data from socket and write to user's screen. */ n = recv(sd, buf, sizeof(buf), 0); while (n > 0) { write(1,buf,n); n = recv(sd, buf, sizeof(buf), 0); } /* Close the socket. */ closesocket(sd); /* Terminate the client program gracefully. */ } exit(0);

/* server.c - code for example server program that uses TCP */ #ifndef unix #define WIN32 #include <windows.h> #include <winsock.h> #else #define closesocket close #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <netdb.h> #endif int visits = 0; /* counts client connections */ /*------------------------------------------------------------------------ * Program: server * * Purpose: allocate a socket and then repeatedly execute the following: * (1) wait for the next connection from a client * (2) send a short message to the client * (3) close the connection * (4) go back to step (1) * * Syntax: server [ port ] * * port - protocol port number to use * * Note: The port argument is optional. If no port is specified, * the server uses the default given by PROTOPORT. * *------------------------------------------------------------------------ */ #include <stdio.h> #include <string.h> #define PROTOPORT 5193 /* default protocol port number */ #define QLEN 6 /* size of request queue */

main(argc, argv) int argc; char *argv[]; { struct hostent *ptrh; /* pointer to a host table entry */ struct protoent *ptrp; /* pointer to a protocol table entry */ struct sockaddr_in sad; /* structure to hold server's address */ struct sockaddr_in cad; /* structure to hold client's address */ int sd, sd2; /* socket descriptors */ int port; /* protocol port number */ int alen; /* length of address */ char buf[1000]; /* buffer for string the server sends */ #ifdef WIN32 WSADATA wsadata; WSAStartup(0x0101, &wsadata); #endif memset((char *)&sad,0,sizeof(sad)); /* clear sockaddr structure */ sad.sin_family = AF_INET; /* set family to Internet */ sad.sin_addr.s_addr = INADDR_ANY; /* set the local IP address */ /* Check command-line argument for protocol port and extract */ /* port number if one is specified. Otherwise, use the default */ /* port value given by constant PROTOPORT */ if (argc > 1) { /* if argument specified */

} else { port = PROTOPORT; /* use default port number */ } if (port > 0) /* test for illegal value */ sad.sin_port = htons((u_short)port); else { /* print error message and exit */ fprintf(stderr,"bad port number %s\n",argv[1]); exit(1); } /* Map TCP transport protocol name to protocol number */ if ( ((int)(ptrp = getprotobyname("tcp"))) == 0) { fprintf(stderr, "cannot map \"tcp\" to protocol number"); exit(1); } /* Create a socket */ sd = socket(pf_inet, SOCK_STREAM, ptrp->p_proto); if (sd < 0) { fprintf(stderr, "socket creation failed\n"); exit(1); } /* Bind a local address and port to the socket */ if (bind(sd, (struct sockaddr *)&sad, sizeof(sad)) < 0) { fprintf(stderr,"bind failed\n"); exit(1); }

/* Specify size of request queue */ if (listen(sd, QLEN) < 0) { fprintf(stderr,"listen failed\n"); exit(1); } /* Main server loop - accept and handle requests */ } while (1) { alen = sizeof(cad); if ( (sd2=accept(sd, (struct sockaddr *)&cad, &alen)) < 0) { fprintf(stderr, "accept failed\n"); exit(1); } visits++; sprintf(buf,"this server has been contacted %d time%s\n", visits,visits==1?".":"s."); send(sd2,buf,strlen(buf),0); closesocket(sd2); }

Αρχιτεκτονική προγραμμάτων Ακολουθία κλήσεων σε πελάτη και εξυπηρετητή

Εξυπηρετητής Αρχικοποίηση: getprotobyname - αναζητά τον αριθμό πρωτοκόλλου για το TCP socket - δημιουργεί ένα socket bind - συσχετίζει ένα socket με local IP και port listen - συσχετίζει ένα socket με πλήθος εισερχόμενων αιτήσεων Loop: accept - αποδέχεται εισερχόμενη αίτηση send - στέλνει μήνυμα στον πελάτη close - κλείνει τη σύνδεση socket

Πελάτης Αρχικοποίηση: gethostbyname - αναζητά τον εξυπηρετητή getprotobyname - αναζητά τον αριθμό πρωτοκόλλου για το TCP socket - δημιουργεί ένα socket connect - συσχετίζει ένα socket και συνδέεται με εξυπηρετητή σε κάποια απομακρυσμένη IP και port που αυτός ο εξυπηρετητής ακούει Loop: recv - λαμβάνει μήνυμα από τον εξυπηρετητή Τερματισμός: close - τερματίζει το socket

ΠΡΟΣΟΧΗ: Κλήσεις recv του πελάτη Γιατί η κλήση στη recv (στον πελάτη) είναι σε ένα loop αφού ο εξυπηρετητής στέλνει μόνο ένα μήνυμα; Aπάντηση: Το λογισμικό πρωτοκόλλων δεν εγγυάται την παράδοση των δεδομένων στα ίδια blocks όπως αυτά δημιουργήθηκαν από τον εξυπηρετητή Μπορεί να ταξιδεύουν σε διαφορετικά TCP segments H recv δεν χρειάζεται να επιστρέψει τόσα δεδομένα όσα της ζητήθηκαν Ο πελάτης πρέπει να κάνει επανειλημένες κλήσεις στην κλήση recv μέχρι αυτή να επιστρέψει 0(EOF)

Μπλοκάρισμα των κλήσεων sockets Οι περισσότερες κλήσεις socket μπλοκάρουν την καλούσα διαδικασία μέχρι η λειτουργία του socket ολοκληρωθεί (προφανώς αποσύρονται από τη λίστα των έτοιμων προς εκτέλεση διαδικασιών) Ο εξυπηρετητής μπλοκάρει: στην accept μέχρι να φθάσει μια νέα σύνδεση στη send μέχρι να παραδοθούν τα δεδομένα στο τοπικό λογισμικό πρωτοκόλλων Ο πελάτης μπλοκάρει: στη gethostbyname μέχρι να επιλυθεί το όνομα του εξυπηρετητή από το DNS στη recv μέχρι να παραδοθεί ένα μήνυμα από τον εξυπηρετητή

Χρήση διαφορετικού εξυπηρετητή (πελάτη) με τον δεδομένο πελάτη (εξυπηρετητή) Αλλες υπηρεσίες χρησιμοποιούν παρόμοια πρωτόκολλα εφαρμογής: DAYTIME CHARGEN Προσδιορίζοντας άλλη πόρτα στον πελάτη αυτός συνδέεται σε διαφορετική υπηρεσία (με άλλα λόγια σε διαφορετικό εξυπηρετητή) Παρομοίως κάποιος διαφορετικός πελάτης που χρησιμοποιεί το ίδιο πρωτόκολλο εφαρμογής μπορεί να χρησιμοποιηθεί για τον έλεγχο του εξυπηρετητή (πχ πελάτης telnet)

Επιπλέον θέματα σχεδίασης και υλοποίησης λογισμικού πελάτη - εξυπηρετητή

Αναζήτηση ενός domain name struct hostent{ char *h_name; /* official host name */ char **h_aliases; /* other aliases */ int h_addrtype; /* address type */ int h_length; /* address length */ int **h_addr_list; /* list of addresses */ } #define h_addr h_addr_list[0] struct hostent *hptr; hptr=gethostbyname( www.unipi.gr ) hptr->h_addr: περιέχει τη δνση IP σε δυαδική μορφή Inet_addr: παίρνει σαν είσοδο ένα ASCII string με την δεκαδική αναπαράσταση της ΙΡ δνσης και επιστρέφει τη δυαδική μορφή της

Αναζήτηση γνωστής υπηρεσίας struct servent{ char *s_name; /* official service name */ char **s_aliases; /* other aliases */ int s_port; /* port for this service */ int s_proto; /* protocol to use */ } struct servent *sptr; sptr=getservbyname( smpt, tcp ) sptr->s_pοrt: περιέχει τον αριθμό πόρτας

Αναζήτηση πρωτοκόλλου struct protoent{ char *p_name; /* official protocol name */ char **p_aliases; /* list of aliases allowed */ int p_proto; /* official protocol number */ } struct protoent *pptr; pptr=getprotobyname( udp ) pptr->p_proto: περιέχει τον αριθμό πρωτοκόλλου

Βιβλιοθήκη για σχεδιασμό και υλοποίηση λογισμικού πελατών socket = connecttcp(machine, service); contcp.cpp socket = connectudp(machine, service); conudp.cpp socket = connectsock(host, service, transport); consock.cpp errexit(format,...); errexit.cpp

Παραδείγματα πελατών Πελάτης TCP υπηρεσίας DAYTIME TCPdtc.cpp Πελάτης UDP υπηρεσίας TIME UDPtime.cpp Πελάτης TCP υπηρεσίας ECHO TCPecho.cpp Πελάτης UDP υπηρεσίας ECHO UDPecho.cpp

Βιβλιοθήκη για σχεδιασμό και υλοποίηση λογισμικού εξυπηρετητών socket = passivetcp(service); passtcp.cpp socket = passiveudp(service); passudp.cpp socket = passivesock(service, transport, qlen); passsock.cpp

Είδη εξυπηρετητών Ακολουθιακός χωρίς σύνδεση συνήθης ειδικά για υπηρεσίες με μικρή επεξεργασία Παράλληλος χωρίς σύνδεση λιγότερο συνήθης και πρέπει ο χρόνος δημιουργίας του νέου thread να είναι σημαντικά μικρότερος της απαιτούμενης επεξεργασίας Ακολουθιακός με σύνδεση λιγότερο συνήθης, για υπηρεσίες με σύνδεση που απαιτούν πολύ μικρή επεξεργασία Παράλληλος με σύνδεση συνήθης για υπηρεσίες με σύνδεση δύο είδη πολλαπλά threads που ακούν σε ένα socket το καθένα ένα thread που ακούει σε πολλά sockets ταυτόχρονα

Ακολουθιακός χωρίς σύνδεση server Server application process Socket σε γνωστή πόρτα Operating system Παράδειγμα : UDPtimed.cpp

Ακολουθιακός με σύνδεση server Server application process Socket σε γνωστή πόρτα για αποδοχή αιτήσεων Socket για κάθε ξεχωριστή αίτηση Operating system Παράδειγμα : TCPdtd.cpp

Παράλληλος με σύνδεση (Υλοποίηση πολλαπλών threads) Master Server Socket σε γνωστή πόρτα για αποδοχή αιτήσεων Slave 1 Slave 2 Slave n... Sockets για κάθε ξεχωριστή αίτηση Server application threads Operating system Παράδειγμα : TCPechod.cpp

Παράλληλος με σύνδεση (Υλοποίηση ενός thread) Server Socket σε γνωστή πόρτα για αποδοχή αιτήσεων... Sockets για κάθε ξεχωριστή αίτηση Server application process Operating system Παράδειγμα : TCPmechd.cpp Προσοχή : κλήση select()

Παράδειγμα παράλληλου προγράμματος Πρόγραμμα που υπολογίζει παράλληλα (δύο threads) το ίδιο άθροισμα κάποιων αριθμών: consum.cpp Πιθανό αναμενόμενο αποτέλεσμα: consum.out