Как определить, закончил ли я чтение () из сокета UNIX? - PullRequest
1 голос
/ 26 февраля 2010

Я читал справочную страницу для read (2), и, согласно man-странице, возвращаемое значение read (2) равно -1 в случае ошибки, 0 в EOF и> 0 для количества прочитанных байтов. ,

Как узнать, когда запись (2) на клиенте завершена?

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

Если я просто упускаю что-то простое, может ли кто-нибудь любезно указать на это или указать мне хороший пример?

Ответы [ 4 ]

3 голосов
/ 26 февраля 2010

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

2 голосов
/ 26 февраля 2010

Вы знаете, что вы сделали, когда read возвращает:

  • -1 - произошла ошибка
  • 0 - EOF
  • Другое ненулевое значение - это наиболее распространенный случай. Протокол должен указать размер своих сообщений, используя либо header , указывающий размер сообщения, либо сообщения фиксированной длины . Затем вы можете отслеживать количество прочитанных байтов, и вы знаете, что все сделано, когда вы прочитали столько байтов. В противном случае вам нужно продолжать читать байты, пока вы не получите полное сообщение.
0 голосов
/ 26 февраля 2010

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

0 голосов
/ 26 февраля 2010

Между чтением и записью нет соответствия. Для полной загрузки одной записи клиента может потребоваться 10 операций чтения. Если вы не добавите разделитель в контент, у вас нет возможности узнать, где находится конец, если сокет не закрыт.

Если вам все еще нужно отправить ответ клиенту, вы можете наполовину закрыть сокет на клиенте:

shutdown(socket, SHUT_WR);

Что приведет к тому, что чтение на сервере вернет 0.

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