Θα δώσω ένα σχήμα θεωρίας για αυτούς που ξεκινάνε τωρα και θα παρατεθεί και ο κώδικας πιο κατω ο οποιος μπορει να τρέξει μεν αλλα παλι τα ιδια και εδω οπως με την php δεν μπορω να δω αν τελικα μου κανει bind ή οχι κάποια port
ΘΕΩΡΙΑ - ΕΙΣΑΓΩΓΗ ΣΤΟΝ ΔΙΚΤΥΑΚΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟ
Καταρχην τι είναι ενα socket?
Socket είναι το ένα άκρο μιας full duplex επικοινωνίας μεταξύ 2 προγραμμάτων που εκτελούνται δηλαδη μιας επικοινωνίας στην οποία μπορώ και να στείλω αλλα και να λάβω ταυτόχρονα. Κάθε πρόγραμμα διαβάζει απο και γράφει σε ενα socket με τρόπο παρόμοιο με της εγγραφής και ανάγνωσης σε ενα filesystem . Στα αρχεία του filesystem μας παίζει ένας δείκτης τύπου FILE* ο οποιος απλα αναφέρει ένα αρχείο δίσκου. Με τον ιδιο τρόπο και για να χειριστούμε ενα socket θα πρεπει να ορίσουμε εναν socket descriptor (στον δικο μου κωδικα θα φαίνεται σαν sd σε άλλους ειναι και σαν socket_desc).
Μια βασική διαφορά στον προγραμματισμό στα sockets μεταξυ C & php έγκειται στις δομές. Η php οπως μου επισήμανε και ο ΑΠοστολης στο θρέντ αποριών της php δεν χρειάζεται να κάνει διαχείριση χαμηλού επιπέδου απλα στην C τα πραγματα ειναι πιο "βαθειά".
Η δομή sockaddr_in (για την οικογένεια πρωτοκολλων IPv4) για να αποθηκεύσει διευθύνσεις και γενικά παρέχουν πληροφορίες στις συναρτήσεις του socket API . Με 2 λογια δηλαδη
μπορεί καποιος να τα διαβασει καλυτερα απο τον Beej's Guide.
Ενας TCP server ξεκινάει με τις ακόλουθες κλήσεις :
socket() -> bind () -> listen() -> accept() /* ΑΠο το σημείο αυτο και μετα γίνεται το TCP 3-way handshake με τον client στην φάση connect() */
και στην συνέχεια υπάρχουν και άλλες κλήσεις οπως η read () , write() και τέλος η close() αυτα για το socket του TCP server
ο client θα έχει τις κλήσεις socket() -> connect() -> write() -> read() και τελος close() (τα βελη δεν εχουν καμια σχεση με δεικτες εδω απλα δειχνουν την ροη) .
Τα παραπανω ειναι απλα συναρτήσεις που υλοποιούν τις αντίστοιχες κλήσεις συστήματος για να καταστεί δυνατή η επικοινωνια και η ανταλλαγη δεδομενων αναμεσα σε εναν server και εναν client συναρτήσεις που περιγράφονται απο το API της C για τα sockets.
socket() -> δημιουργία και αρχικοποίηση ενος socket
επιστρέφει εναν ακέραιο ανάλογο με τις ρουτίνες διαχείρισης αρχείων.
Η συνάρτηση που το υλοποίει στην C είναι ->
- Κώδικας: Επιλογή όλων
int socket(int family,int type, int protocol)
δηλαδη συμφωνα και με τα παραπάνω
- Κώδικας: Επιλογή όλων
int sd;
sd=socket(AF_INET,SOCKSTREAM,0);
/*AF_INET για πρωτοκολλα ιντερνετ
SOCK_STREAM ΓΙΑ TCP συνδεσεις
Η τιμη 0 ειναι η τιμη που θα επιστραφει κατα την επιτυχη εκτελεση */
Η συνάρτηση bind() απλά δεσμεύει το sd που έχει επιστρέψει η κλήση socket() με μια τοπικη διεύθυνση και μια θυρα "λεγοντας" στο συστημα οτι τα μηνύματα που έρχονται στα συγκεκριμένα port-interface απευθύνονται στην συγκεκριμένη διαδικασία.
Η κλήση listen() ειναι προαιρετική. H συνάρτηση αυτη θα δέχεται εισερχόμενες συνδέσεις στην socket του συστήματος που ήδη έχει δεσμευτεί απο την bind μολις γίνει μια επιτυχής σύνδεση ένας νέος περιγραφέας υποδοχής επιστρέφεται και μπορει να χρησιμοποιηθεί για την επικοινωνία του προγράμματος.
Η connect() απλα αρχικοποιεί τα TCP sockets με το handshaking .
H κλήση accept() κάνει ουσιαστικα αποδοχή μιας αίτησης σύνδεσης που περιμένει στην ουρά του sd. Αν η ουρά είναι άδεια η διεργασία μπλοκάρει (εδω ουσιαστικα εννοει μιας και οσοι έχουν διαβάσει για τους servers θα έχουν διαβάσει και για τις διεργασίες δαίμονες που περιμένουν στο παρασκήνιο κάποια αίτηση απο καποιον client για να την επεξεργαστούν και μέχρι τοτε απλα βρίσκονται στο παρασκήνιο καπως ετσι ειναι και εδω) μεχρι να εμφανιστεί κάποια αίτηση μολις γίνει η αποδοχή επιστρέφονται πληροφορίες για τον client (port,IP) και ενας νέος descriptor new_sd που αποτελεί πλεον το ακρο ενος καινουργιου καναλιού.
Οι κλήσεις read()-write() κάνουν οτι λεει και το ονομα τους αναγνωση και εγγραφη δηλαδη και τελος η συνάρτηση close() κλείνει το socket που έχει δημιουργηθεί με την αντίστοιχη κλήση. Ακολουθεί κώδικας για connect() & bind().

