Страницы

Поиск по вопросам

среда, 5 февраля 2020 г.

Что происходит когда сокет записывает данные в то время, когда с другой стороны читаются предыдущие данные?

#cpp #qt5 #tcp #сокеты


К примеру у меня есть сокет, который в цикле (2 итерации к примеру) записывает данные
подряд. При этом на другом конце (где этот сокет прослушивается) в это время происходит
считывание. Так вот, что будет когда происходит вторая попытка записи данных в сокет,
когда на другом конце еще считывается первая часть пересланых данных?
    


Ответы

Ответ 1



Если сокет блокирующий и на чтение запрошено больше данных, чем Вы отправляете - будет ждать "второй итерации". Если сокет неблокирующий - вычитает, сколько сможет, и затем Вам снова придется опрашивать сокет. В связи с комментарием @VTT хочу дать немного более развернутый ответ. Если вызывается одна из функций read/recv/recvfrom для блокируемого сокета и при этом в буфере нет никаких данных - сокет переходит в спящее состояние до тех пор, пока не придут какие-либо данные. Достаточно одного байта. Тем не менее, мы можем задать флаг MSG_WAITALL - в этом случае мы будем ждать до тех пор, пока не будет доступно фиксированное (запрошенное нами) количество байт. В случае неблокируемого сокета - если не удовлетворены условия ввода - то ф-ия вернет управление установив ошибку EWOULDBLOCK. Если вызывается одна из функций write/send/sendto - данные копируются из буфера приложения в буфер отправки сокета. Для блокируемого сокета - если в буфере отправки недостаточно места, процесс переходит в состоянии оидания до тех пор, пока это самое место не освободится. Для неблокируемого сокета - если в буфере отправки недостаточно места - ф-ия вернет управление, установив ошибку EWOULDBLOCK. Комбинируйте и предполагайте наиболее вероятный результат того, чем же все-таки окончится посылка двух сообщений :)

Ответ 2



В общем случае, попытки записи и чтения данных будут не связаны. Вторая попытка записи может происходить совершенно независимо от поведения (или даже от наличия) партнера на другой стороне. Более того, когда вызов функции записи на первой итерации успешно вернется, нет оснований полагать, что только что отправленные данные на самом деле куда-то ушли. Если активирован алгоритм Нейгла, то только что посланные данные могут спокойно сидеть в буфере на стороне отправителя. Даже если подкрутить настройки (допустим TCP_NODELAY), то данные на момент второго вызова записи могут еще быть где-то в пути, или сидеть в буфере на принимающей стороне.

Комментариев нет:

Отправить комментарий