Это зависит от того, какое поведение вы хотите и какая структура программы. По умолчанию сокет будет блокироваться при любых операциях чтения или записи, а это означает, что если ваша попытка и ваш основной поток вашего сервера опросит соединение, вы закончите с ним «замораживание» в течение 3 минут или до тех пор, пока клиент не закроет связь.
Абсолютное простейшее функциональное решение (без многопоточности) заключается в том, чтобы установить сокет на неблокирование и опросить основной поток. Похоже, вы хотите избежать этого.
Наиболее очевидным способом является создание выделенного потока для каждого соединения, а также основного гнезда слушателя. Ваш сервер прослушивает входящие соединения и порождает поток для каждого создаваемого потока. Затем каждый соединительный поток блокируется в своем сокете до тех пор, пока он не получит данные, и либо обрабатывает его сам, либо шунтирует его в общую очередь. Это громоздкое и сложное решение - несколько потоков, которые требуют открытия и закрытия, общие ресурсы, которые нуждаются в защите.
Другой вариант - установить сокет в неблокирующее (в win32 использовать setsockopt, чтобы установить тайм-аут, в * nix передать ему флаг O_NONBLOCK). Таким образом, он вернет управление, если нет данных для чтения. Однако это означает, что вам необходимо опросить сокет через разумные промежутки времени («разумно» полностью зависит от вас и как быстро вам понадобится сервер для работы с новыми данными.)
Лично для облегченного использования вы описываете Я бы использовал комбинацию из вышеперечисленного: отдельный выделенный поток, который каждые несколько секунд проверяет сокет (или массив неблокирующих сокетов), спящий между ними, и просто подталкивает данные в очередь для основного потока, чтобы действовать во время это основной цикл.
Есть много способов попасть в беспорядок с асинхронными программами, поэтому, вероятно, лучше всего держать его простым и заставить его работать, пока вам не станет удобно управлять потоком.
Что делать, если я закрываю соединение каждый раз, когда я что-то посылаю, и открываю новое соединение в следующий раз, когда мне нужно что-то послать, таким образом я избегу блокировки. Как это звучит? –
Да, вы можете это сделать (И действительно, вы можете также, если вы только нажимаете обновления статуса). Проблема в том, что сервер будет блокировать accept(), а не только при чтении данных. В основном ваш сервер не может гарантировать, когда соединение произойдет, и, следовательно, его нужно постоянно слушать. Вы можете установить тайм-аут (на обоих концах) и полагаться на обе стороны, зная время, когда они предназначены для формирования соединения, но это немного склонно к ошибке. Изменить: Но если единственное, что нужно сделать вашему серверу, это обновление статуса процесса, тогда да, это будет нормально работать. – Bhau
Ну, я не против, если сервер постоянно слушает. Моя первоначальная проблема заключалась в том, что я вызывал send(), не закрывая соединение, и только первый статус был бы отправлен, и я читал здесь в аналогичном случае (http://stackoverflow.com/q/8347107/777510) что мне нужно было вызвать recv и отправить в цикле, чтобы этого избежать, и то, о чем я прошу, это то, что я могу каким-то образом избежать этого цикла, возможно, путем отправки и закрытия соединения. Так что с этим все в порядке? –