Για σας.
Έφτιαξα αυτόν τον οδηγό διότι μου το ζήτησε ένα παιδί από την κοινότητα.
Λοιπός ας ξεκινήσουμε.
Προτού πω για το module socket της python, πρώτα θα πρέπει να σας εξηγήσω τη είναι τα bytes
(τουλάχιστον για όσους δεν ξέρουν), διότι τα προγράμματα που στέλνουν πληροφορίες μέσου του
διαδικτύου τα στέλνουν σε μορφή bytes, επομένως θα πρέπει να γνωρίζετε τη είναι.
Ένα byte είναι ένας δυαδικός αριθμός που αποτελείτε από 8 ψηφία 0 και 1. Δηλαδή αυτό εδώ 01101101
είναι ένα byte.Τα bytes αναπαριστούν δεδομένα,όπως για παράδειγμα έναν χαρακτήρα πχ το 'α' ή οτιδήποτε άλλο μπορεί να χαρακτηριστεί δεδομένο σε μια γλώσσα προγραμματισμού.
Επειδή ο υπολογιστής δεν μπορεί να καταλάβει τη είναι το 'α' για παράδειγμα, χρειάζεται να το
δει ως ένα byte.
Στην python υπάρχει το build in module socket το οποίο επιτρέπει την αποστολή και την παραλαβή
bytes μέσο του διαδικτύου.Μπορείτε πολύ απλά να το περιλάβετε στο πρόγραμμα σας έτσι:
import socket.
Φανταστείτε το socket ως μία "γέφυρα" η οποία ενώνει έναν υπολογιστή με έναν άλλον έτσι ώστε
να μπορούν τα δεδομένα να μεταφερθούν από τον ένα υπολογιστή στον άλλον.
Ας αρχίσουμε με ένα παράδειγμα.
import socket
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Αυτό που έκανα προηγουμένως είναι η δημιουργία ενός αντικειμένου τύπου socket.
Αυτό το χρησιμοποιούμε για να κάνουμε οτιδήποτε έχει σχέσει με την αποστολή και παραλάβει
bytes.
Στις παρενθέσεις έχω δώσει 2 παραμέτρους.Η πρώτη παράμετρος ονομάζετε family του socket
και αντιπροσωπεύει ένα tuple (ip, port).Στην ουσία λέω στο socket μου ότι θέλω να χρησιμοποιώ
ένα ip και ένα port για να συνδεθώ σε άλλους υπολογιστές ή να δημιουργήσω ένα server.
Υπάρχουνε και άλλα είδη family αλλά ο ποίο διαδεδομένος είναι ο AF_INET και σας προτείνω να
χρησιμοποιείτε πάντα αυτόν.Άμα θέλετε να τα μάθετε όλα αυτά μπορείτε να δείτε το document της
python για τα sockets.
H δεύτερη παράμετρος είναι ο τύπος του socket (TCP ή UDP).Εδώ χρησιμοποιώ το πρωτόκολλο tcp
λέγοντάς στην python ότι θέλω να χρησιμοποιήσω τον τύπο SOCK_STREAM.Σας προτείνω να χρησιμοποιείτε πάντα αυτόν τον τύπο για τι είναι ο ποιο διαδεδομένος.
Άμα θέλετε να μάθετε πλήρως τη συμβαίνει ακριβώς με αυτές τις παραμέτρους τότε θα πρέπει
να μάθετε για τα πρωτόκολλα του διαδικτύου.Αλλά άμα δεν σας ενδιαφέρουν δεν χρειάζεται.
Ακόμα και αν δεν καταλάβατε τη κάνουν αυτές η παραμέτρους δεν υπάρχει πρόβλημα αρκεί κάθε
φορά που θέλετε να φτιάξετε ένα πρόγραμμα που να χρησιμοποιεί sockets πρέπει να δημιουργείτε
ένα object (αντικείμενο) με αυτόν τον τρόπο: socket.socket(socket.AF_INET, socket.SOCK_STREAM)
Στην συνέχεια θα σας δείξω πως λειτουργεί ένας server.
import socket
#-----Μεταβλητές-----#
ip = ""
port = 5555
INET_tuple = (ip, port)
#-----Μεταβλητές-----#
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SOCKET.bind( INET_tuple )
SOCKET.listen(1)
client, address = SOCKET.accept()
Πρώτα ορίζω κάποιες μεταβλητές.Στην συνέχεια δημιουργώ ένα αντικείμενο τύπου socket.
Μετά "δένω" το socket μου με το SOCKET.bind() στον υπολογιστή μου, δηλαδή φανταστείτε
ότι έχω ενώσει αυτήν την γέφυρα που έλεγα προηγουμένως στον υπολογιστή μου.Η bind() παίρνει
ως παράμετρο ένα tuple με δύο πράματα μέσα.Τον ip ο οποίο είναι μια συμβολοσειρά και το port
το οποίο είναι ένας ακέραιος αριθμός.Το port μπορεί να είναι ένας οποιοδήποτε αριθμός από
0 - 1023 .Δίνοντας για ip τον κενώ χαρακτήρα "",εννοώ τον τοπικό ipv4 του υπολογιστή μου.
Για να δείτε τη ip έχει ο υπολογιστής σας ανοίξτε τον cmd των windows και γράψτε ipconfig .
Ψάξτε εκεί που λέει ipv4 και δείτε ποιος είναι.Στην συνέχεια με το SOCKET.listen(1), λέω
στον socket μου ότι περιμένω μόνο ένας client(υπολογιστής) να συνδεθεί στον server μου.
Μετά με το socket.accept() το socket περιμένει μέχρι να συνδεθεί ο client στον server μου.
Το πρόγραμμα "κολάι" σε εκείνη την γραμμή μέχρι να συνδεθεί ο client.Μόλις συνδεθεί, το socket
επιστρέφει ένα tuple με δύο πράματα μέσα.Πρώτα ένα αντικείμενο τύπου socket το οποίο στο
συγκεκριμένο παράδειγμα αποθηκεύετε στην μεταβλητή client και δεύτερον ακόμα ένα tuple το
οποίο περιέχει την διεύθυνση του client δηλαδή τον ip και το port από όπου συνδέθηκε.
Χρειάζεσαι οπωσδήποτε την μεταβλητή client για να μπορεί ο server να στέλνει δεδομένα στον
client.
Μέχρι τώρα όμως δημιουργήσαμε τον server και ενώσαμε την γέφυρα μόνο στον ένα υπολογιστή.
Τώρα θα σας δείξω από τη αποτελείτε το script του client.
import socket
#-----Μεταβλητές-----#
ip = "192.168.1.15"
port = 5555
INET_tuple = (ip, port)
#-----Μεταβλητές-----#
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SOCKET.connect(INET_tuple)
Eδω κάναμε ότι και προηγούμενος με μία διαφορά.Καλέσαμε την SOCKET.connect() για να συνδεθούμε
σε ένα άλλο socket το οποίο έχει είδη κάνει bind και περιμένει για clients.H connect παίρνει ένα
tuple με τον ip του υπολογιστή που θέλουμε να συνδεθούμε και με port το port που
χρησιμοποιήθηκε για το bind του socket στο script του server.Στην ουσία συνδεθήκαμε στην "γέφυρα"
στην οποία είναι δεμένος ο server μας και τώρα είμαστε έτοιμη για μεταφορά δεδομένων.
#Server
import socket
#-----Μεταβλητές-----#
ip = ""
port = 5555
message = "Είσαι καλά?"
INET_tuple = (ip, port)
#-----Μεταβλητές-----#
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SOCKET.bind( INET_tuple )
SOCKET.listen(1)
client, address = SOCKET.accept()
client.sendall( str.encode(message) )
Με το client.sendall μπορούμε να στείλουμε bytes στον client.Σε αυτήν την περίπτωση
θέλω να στείλω ένα μήνυμα.Πρώτα πρέπει να μετατρέψω την συμβολοσειρά σε bytes και μετά
να την στείλω διότι η sendall στέλνει bytes. Με την str.encode() μετατρέπω την συμβολοσειρά
μου σε bytes και στην συνέχεια τα στέλνω στον client με την sendall.
#Client
import socket
import sys
#-----Μεταβλητές-----#
ip = "192.168.1.15"
port = 5555
INET_tuple = (ip, port)
#-----Μεταβλητές-----#
SOCKET = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
SOCKET.connect(INET_tuple)
message_bytes = SOCKET.recv(100)
print( bytes.decode(message_bytes) )
Με την SOCKET.recv(100) περιμένω να λάβω 100 bytes.Το πρόβλημα εδώ είναι ότι δεν γνωρίζω πόσα
bytes θα μου στείλει ο server αλλά για το συγκεκριμένο παράδειγμα 100 bytes φτάνουν σίγουρα.
Θα δούμε ποιο μετά πως λύνεται αυτό το πρόβλημα.
Στην συνέχεια για να εμφανίσω το μήνυμα στην οθόνη πρέπει πρώτα να μετατρέψω το bytes σε συμβολοσειρά.Αυτό το κάνω με την συνάρτηση bytes.decode().Στην συνέχεια εμφανίζω την συμβολοσειρά
μου με την print().
Αυτά είναι αρκετά για αρχή.Ότι απορίες έχετε μπορείτε να μου τις γράψετε.
Φτιάξτε αυτά τα δύο scripts και δοκιμάστε να δείτε αν δουλεύουν και αν καταλάβατε πως δουλεύουν.