2015-04-28 5 views
0

Этот вопрос не для конкретной реализации того, как это делается. Это больше касается концепции и дизайна отправки информации через Интернет с помощью своего рода протокола - либо TCP, либо UDP. Я знаю только, что нужны сокеты, но мне интересно об остальном. Например, после того, как соединение сделано, и вы передаете информацию через это, но как другой конец прослушивает конкретный порт и постоянно его прослушивает? Выполняется ли прослушивание в фоновом режиме, ожидая получения информации? (Чтобы иметь возможность делать другие вещи/обрабатывать во время ожидания информации) Так что, по сути, я думаю, что реальный пример того, как такое приложение работает на высоком уровне, будет достаточным для объяснения потока данных. Например, отправка файлов в Skype или что-то подобное.Отправка и получение данных через Интернет

P.S. Большинство других вопросов по подобным темам касаются конкретной реализации или ошибки, которую кто-то имеет.

+0

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

ответ

0

То, что я в настоящее время сделать в приложении является следующим с использованием POSIX сокеты с протоколом TCP:

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

Сервер прослушивает определенный порт пока клиент не подключится. После подключения вы получите новый дескриптор файла сокета для связи с клиентом, в то время как исходный сокет может прослушивать новые подключения. Затем мой сервер создает новый поток для обработки этого клиента, ожидая новых соединений в исходном сокете. В новом потоке сервер ожидает команды запроса от клиента (например, токена входа в систему). После того как запрос был получен сервером, сервер соберет свои данные, упакует их вместе с помощью буферов протокола Google и отправит их клиенту. Клиент теперь либо сообщает серверу о прекращении сеанса (если все данные получены клиентом, в котором он нуждается), либо отправляет другой запрос.

В основном идея на моем сервере. Большая проблема заключается в том, как вы передаете и получаете данные. Например. вы не можете отправлять структуры или классы (по крайней мере, не через C++) по кабелю, вам нужен какой-то сериализатор, и вы должны убедиться, что другая часть знает, сколько нужно получить. Так что я делаю, сначала отправьте целое число 4 байта по проводу, содержащему размер входящего пакета, а затем отправьте сам пакет с помощью сериализатора (в моем случае буферов протокола Google). Другая сторона ожидает, что будет доступно 4 байта, зная, что это будет размер входящего пакета. После приема 4 байтов программа ожидает получения точного количества данных, доступных в сокете, когда она доступна, считывает данные из буфера и десериализует их. Когда сокет не получает данные в течение 30 секунд, активируйте тайм-аут и завершите соединение.

То, что вам всегда нужно знать, это консистенция систем. Например. система большого конца (например, PowerPC) и небольшая системная система (например, x86) будут иметь проблемы, когда вы отправляете целое число непосредственно по проводу. Например

0001 

на x86, является

1000 

на ПК питания, таким образом, делая 8 из 1. Таким образом, вы всегда должны использовать такие функции, как ntohl, в Htonl, который будет преобразовывать данные из и в адрес байта байта от и к порядку байта сети (сетевой порядок байтов всегда большой endian). Надеюсь, что это поможет. Я мог бы также предоставить вам некоторый код, если это поможет.

+0

Благодарим за ответ! Это то, что я искал в ответ. Чтобы сделать это более ясным, я предполагаю, что поток на сервере использует бесконечный цикл, который постоянно пытается найти соединение, а когда он это делает - он запускает второй поток для подключенного клиента. Это верно? P.S. Я бы поднял ваш ответ, но мне не хватает репутации, извините. – MZokov

+0

В принципе да. Но функция connect() будет блокироваться до тех пор, пока соединение не соберется, поэтому нет необходимости помещать поток в режим сна. Приходит очень удобно. – Nidhoegger