Почему мы должны читать () перед записью () в программе сервера TCP? - PullRequest
0 голосов
/ 20 марта 2010

Насколько я понимаю, простой TCP-сервер будет кодироваться следующим образом.

socket () - bind () - listen () - accept () - read () - write ()

Клиенты будут написаны следующим образом.

socket () - bind () (необязательно) - connect () - write () - read ()

Обратите внимание на разницу в порядке вызовов read () и write () между клиентской и серверной программой.

Требуется ли всегда выполнять read () перед write () в серверной программе и если, то почему?

Спасибо, Naga

Ответы [ 4 ]

3 голосов
/ 20 марта 2010

Это не обязательно, но для сервера имеет смысл прочитать запрос перед тем, как написать ответ. Обратите внимание, что необходимо читать с обеих сторон достаточно часто, чтобы предотвратить распределенную тупиковую ситуацию: например, если обе стороны пытаются писать, а не читать, промежуточные буферы заполнятся, и ни одна из них не сможет выполнить запись. продолжить. Одним из решений этого является создание отдельного потока, который продолжает чтение, если есть что прочитать (это относится как к клиенту, так и к серверу).

2 голосов
/ 20 марта 2010

Простой ответ - нет. Вы можете делать все, что захотите.

Тем не менее, я предупрежу об этом быстро, поскольку большинство протоколов предназначены для ожидания отправки клиентом чего-либо. В конце концов, сервер по своей природе обслуживает запросы и должен ждать, чтобы узнать, что это за запрос, будь то «GET /», «HELO» или что-то еще. Таким образом, вполне естественно, что сервер читает перед тем, как написать ответ клиенту.

Тем не менее, вы могли бы, если бы захотели, передать информацию о версии клиенту, прежде чем приступить к чтению. Чтобы увидеть эффект, подключитесь к вашему серверу, используя telnet.

1 голос
/ 20 марта 2010

Вы можете выполнять их в любом порядке. Однако сервер обычно генерирует ответ от операции read (), а затем записывает его с помощью операции write (), поэтому этот порядок имеет смысл.

Если вы работаете с несколькими клиентами, вы должны использовать мультиплексор, такой как select, чтобы уведомлять вас, когда у клиентов есть данные, готовые для чтения, чтобы ваш сервер не блокировался каждый раз, когда вы пытаетесь прочитать () с клиента, который ничего не отправил.

0 голосов
/ 20 марта 2010

Это не обязательно, серверная программа может записывать в сокет без предварительного чтения. Но во многих случаях серверная программа должна знать, чего хочет клиент - поэтому сначала она вызывает read ().

...