Ο πελάτης τελειώνει την αποστολή, ο διαμεσολαβητής βλέπει EOF και η απάντηση εξαφανίζεται. Το άμεσο κλείσιμο και των δύο υποδοχών του διαμεσολαβητή μπορεί να προκαλέσει ακριβώς αυτή την ακολουθία. Σε ένα ρελέ TCP, ένα τακτοποιημένο τέλος προς τη μία κατεύθυνση δεν σημαίνει ότι η άλλη κατεύθυνση έχει τελειώσει.

Σκεφτείτε έναν πελάτη που στέλνει αίτημα, κλείνει την πλευρά αποστολής του και περιμένει την απάντηση:

client -- request, then FIN --> proxy --> service
client <-------- reply ------- proxy <-- service

Ο διαμεσολαβητής έχει δύο συνδέσεις TCP και δύο ροές byte που κινούνται ανεξάρτητα. Πρέπει να μεταφέρει την ένδειξη τέλους εισόδου προς τα εμπρός, αφού μεταφέρει τα byte που προηγούνται από αυτήν.

Εκκενώστε την ουρά πριν προωθήσετε το EOF

Σε λήψη μη μηδενικού μεγέθους σε ροή TCP, η επιστροφή μηδενός δηλώνει τακτοποιημένο τέλος αυτής της εισερχόμενης ροής. Σημειώστε αυτή την κατεύθυνση ανάγνωσης ως ολοκληρωμένη. Σταματήστε να περιμένετε περισσότερη είσοδο από αυτήν, αλλά διατηρήστε τα byte που είναι ήδη στην ουρά για την απέναντι υποδοχή.

Όταν η ουρά από τον πελάτη προς την υπηρεσία εκκενωθεί, καλέστε shutdown(service_socket, SHUT_WR) σε υποδοχή POSIX. Αυτό τερματίζει την περαιτέρω μετάδοση προς την υπηρεσία, αφήνοντας διαθέσιμη την κατεύθυνση από την υπηρεσία προς τον πελάτη. Όταν η υπηρεσία ολοκληρώσει την απάντησή της, εφαρμόστε την κατοπτρική πράξη αφού εκκενώσετε την ουρά της απάντησης.

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

Η ετοιμότητα είναι πρόσκληση για ανάγνωση

Μια αναγνώσιμη υποδοχή μπορεί να έχει δεδομένα ή συνθήκη EOF. Καλέστε recv και ερμηνεύστε το αποτέλεσμα. Οι θετικοί αριθμοί είναι byte προς προώθηση· το μηδέν είναι το τέλος της κατεύθυνσης. Σε μη μπλοκαρισμένη υποδοχή, το EAGAIN ή το EWOULDBLOCK σημαίνει ότι αυτή τη στιγμή δεν υπάρχει άλλη είσοδος, ενώ το EINTR μπορεί να απαιτεί επανάληψη. Κανένα από τα δύο δεν είναι το ίδιο γεγονός με το EOF.

Μην αναζητάτε σημαία FIN στον buffer byte που επιστράφηκε. Το TCP παραδίδει μια διατεταγμένη ροή byte σε αυτό το API· τα όρια πακέτων και το τμήμα FIN δεν είναι συνηθισμένο ωφέλιμο φορτίο εφαρμογής.

Αυτός είναι ο κύκλος ζωής μιας ακατέργαστης σήραγγας byte. Ένας διαμεσολαβητής HTTP που αναλύει μηνύματα πρέπει ακόμη να σέβεται τη δομή HTTP, και ένας διαμεσολαβητής που τερματίζει TLS έχει επίσης πρωτόκολλο τερματισμού TLS. Κρατήστε αυτές τις αποφάσεις πρωτοκόλλου πάνω από το κατευθυντικό ρελέ TCP.

Σχετικά άρθρα