2012-04-13 3 views
0

Это мое дело, у меня есть сервер, который прослушивает подключения, и клиент, который я сейчас программирую. Клиенту нечего получать с сервера, но он должен отправлять обновления статуса каждые 3 минуты.Соединение с клиентом и сервером только отправка не принимается

У меня есть следующие в данный момент:

WSAStartup(0x101,&ws); 
    sock = socket(AF_INET,SOCK_STREAM,0); 
    sa.sin_family = AF_INET; 
    sa.sin_port = htons(PORT_NET); 
    sa.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    connect(sock,(SOCKADDR*)&sa,sizeof(sa)); 
    send(sock,(const char*)buffer,128,NULL); 

Как должен быть мой подход? Могу ли я избежать циклического возврата?

ответ

0

Это зависит от того, какое поведение вы хотите и какая структура программы. По умолчанию сокет будет блокироваться при любых операциях чтения или записи, а это означает, что если ваша попытка и ваш основной поток вашего сервера опросит соединение, вы закончите с ним «замораживание» в течение 3 минут или до тех пор, пока клиент не закроет связь.

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

Наиболее очевидным способом является создание выделенного потока для каждого соединения, а также основного гнезда слушателя. Ваш сервер прослушивает входящие соединения и порождает поток для каждого создаваемого потока. Затем каждый соединительный поток блокируется в своем сокете до тех пор, пока он не получит данные, и либо обрабатывает его сам, либо шунтирует его в общую очередь. Это громоздкое и сложное решение - несколько потоков, которые требуют открытия и закрытия, общие ресурсы, которые нуждаются в защите.

Другой вариант - установить сокет в неблокирующее (в win32 использовать setsockopt, чтобы установить тайм-аут, в * nix передать ему флаг O_NONBLOCK). Таким образом, он вернет управление, если нет данных для чтения. Однако это означает, что вам необходимо опросить сокет через разумные промежутки времени («разумно» полностью зависит от вас и как быстро вам понадобится сервер для работы с новыми данными.)

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

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

+0

Что делать, если я закрываю соединение каждый раз, когда я что-то посылаю, и открываю новое соединение в следующий раз, когда мне нужно что-то послать, таким образом я избегу блокировки. Как это звучит? –

+0

Да, вы можете это сделать (И действительно, вы можете также, если вы только нажимаете обновления статуса). Проблема в том, что сервер будет блокировать accept(), а не только при чтении данных. В основном ваш сервер не может гарантировать, когда соединение произойдет, и, следовательно, его нужно постоянно слушать. Вы можете установить тайм-аут (на обоих концах) и полагаться на обе стороны, зная время, когда они предназначены для формирования соединения, но это немного склонно к ошибке. Изменить: Но если единственное, что нужно сделать вашему серверу, это обновление статуса процесса, тогда да, это будет нормально работать. – Bhau

+0

Ну, я не против, если сервер постоянно слушает. Моя первоначальная проблема заключалась в том, что я вызывал send(), не закрывая соединение, и только первый статус был бы отправлен, и я читал здесь в аналогичном случае (http://stackoverflow.com/q/8347107/777510) что мне нужно было вызвать recv и отправить в цикле, чтобы этого избежать, и то, о чем я прошу, это то, что я могу каким-то образом избежать этого цикла, возможно, путем отправки и закрытия соединения. Так что с этим все в порядке? –

Смежные вопросы