Как функция сокета recv обнаруживает конец сообщения - PullRequest
0 голосов
/ 06 октября 2019

Посмотрите на эти небольшие базовые программы на Python:

import socket

tcpsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpsock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
tcpsock.bind(("", 10000))

tcpsock.listen(10)
(sock, (ip, port)) = tcpsock.accept()

s = sock.recv(1024)
print(s)

Вторая программа:

import socket
import time

sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 10000))
time.sleep(1)
sock.sendall(b'hello world')

Первая программа - это сокет-сервер. Он получает сообщение через сокет и отображает его на консоли. Вторая программа - это клиент, который подключается к серверу и отправляет ему сообщение.

Как видите, сервер читает сообщение максимальной длины 1024 байта. Мой клиент отправил несколько байтов. У меня такой вопрос: как сервер узнает, что сообщение заканчивается после символа 'd'?

Я работаю с сокетами годами и всегда внедрял механизм разделителя, чтобы знать, когда сообщение останавливается. Но, похоже, работает автоматически. Мой вопрос: как? Я знаю сообщения об фрагментах TCP-машины. Так что же произойдет, если в середине моего сообщения будет растерзан пакет? Это управляется ОС?

Спасибо

1 Ответ

3 голосов
/ 06 октября 2019

Как сервер знает, что сообщение заканчивается после символа 'd'?

Это не так. В TCP даже нет понятия сообщения. recv просто возвращает то, что есть: оно блокирует, если нет доступных данных, и возвращает то, что может быть прочитано до заданного размера, если данные доступны. «Доступные данные» означают, что в буфере приема сокетов есть данные, которые помещаются туда ядром ОС. Другими словами: recv не будет блокироваться до тех пор, пока не будет возвращено запрошенное число байтов, но оно уже вернется, когда хотя бы один байт находится в буфере приема сокетов.

Например, если клиент сделаетдва send или sendall вскоре после этого один recv может вернуть оба "сообщения" вместе. Это можно легко запустить, отложив recv (добавьте немного сна перед этим), чтобы оба «сообщения» гарантированно были доставлены клиенту.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...