Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
Долго не мог решить в какой раздел форума обратиться с этим вопросом. В исходном коде, как я понимаю, мы регистрируем функцию on_async_accept, которая будет вызвана если на определенный порт поступит запрос на соединение. Пробовал запустить эту программу и подключался с помощью ncat. Функция вызывается. $ Когда происходит новое подключение, то создается новый сокет привязанный к другому порту, как я могу узнать какой этот порт, чтобы обмениваться данными с "клиентом"? И вообще не бред ли строка начинающаяся со знака $ Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 16:37 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_И вообще не бред ли строка начинающаяся со знака $ Бред конечно :) aybek_$ Когда происходит новое подключение, то создается новый сокет привязанный к другому порту, как я могу узнать какой этот порт, чтобы обмениваться данными с "клиентом"? При accept новый сокет действительно создается, но порт у него тот же, что и слушающего сокета. В любом случае назначенные сокету порты/адреса можно получить так: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 16:49 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
Но как тогда возможно одновременно принятие других соединений и обмен данными через существующие? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:08 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_Но как тогда возможно одновременно принятие других соединений и обмен данными через существующие? Каждое соединение идентифицируется кортежем из 4-х элементов: client_ip:client_port - server_ip:server_port. У каждого нового соединения к одному и тому же серверу будет свой client_ip:client_port. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:14 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
а как можно получить адрес созданного при подключении сокета? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:16 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
И так к слову, вам вообше не обязательно знать про порты чтобы принимать/отправлять данные. Сокет как раз служит абстракцией более высокого уровня и снимает этот вопрос. Еще одно. Исходя из предыдущего моего сообщения, сервер может принимать произвольное (неограниченное портами сервера) кол-во соединений, так как его порты не расходуются. Ограничение состоит только в наличии памяти на сервере и наличии свободных портов у клиентов. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:18 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_а как можно получить адрес созданного при подключении сокета? А это я для кого писал? Anatoly MoskovskyВ любом случае назначенные сокету порты/адреса можно получить так: Код: plaintext 1. 2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:19 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
С помощью сокет Sock мы слушаем, при подключении создается новый сокет, говоря адрес сокета, я имел ввиду указатель на него или переменную, чтобы можно было далее к этому сокету применять оперции read & write ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 17:23 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_, Самое простейшее - передавать ссылку на сокет в каждый обработчик одним из аргументов. При этом разумеется ссылка/указатель должны оставаться валидными (указывать на все еще существующий объект) при вызове обработчика. Для этого удобее всего использовать смартуказатели, например boost::shared_ptr. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. Но обычно, кроме сокета нужно еще много чего хранить, поэтому все организуют в виде класса Connection в котором сокет - одно из полей, а обработчики - методы этого класса, и таким образом неявно в каждый обработчик через this передается экземпляр класса, в котором есть все нужное состояние (включая сокет) для дальнейшей обработки соединения. Чтобы эта схема работала с shared_ptr - почитайте про shared_from_this() - он служит для получения shared_ptr на текущий объект из метода этого объекта. К сожалению поля этого форума слишком узки, чтобы я, после честно заслуженного пива, мог написать подробнее :) Зато есть пример в доке Boost.Asio http://www.boost.org/doc/libs/1_55_0/doc/html/boost_asio/example/cpp03/echo/async_tcp_echo_server.cpp ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2014, 21:50 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
получается, что вы создаете сокет, после того как на него подключается какой-то клиент, вы просто передаете сокет обработчику, а сами уже создаете НОВЫЙ сокет и на нем заново слушаете. Как я правильно понял, принцип работы таков: Вы создаете сокет и он сидит ждет подключения. После того как к нему подключатся, он уже становится не слушающим сокетом, а уже сокетом общения некого клиента с сервером. После того как этот сокет стал таким, вы берете и назначаете новый слушающий сокет, которого ждет та же участь ). Никакой сокет при acceptинге автоматически не создается, не так ли? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2014, 23:03 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_Как я правильно понял, принцип работы таков: Вы создаете сокет и он сидит ждет подключения. После того как к нему подключатся, он уже становится не слушающим сокетом, а уже сокетом общения некого клиента с сервером. После того как этот сокет стал таким, вы берете и назначаете новый слушающий сокет, которого ждет та же участь ). Никакой сокет при acceptинге автоматически не создается, не так ли? Нет, вообще не так. Слушает один и тот же сокет, тот что внутри объекта acceptor. Объекты socket, которые создаются перед каждым приемом нового соединения, не несут в себе никакие сокеты пока не будет принято новое соединение. И только в момент прихода нового соединения объект acceptor создает в объекте socket реальный сокет для этого соединения. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.01.2014, 23:14 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
Аха, круто! Теперь все начало получаться. Это часть кода где выполняется обработка принятых сообщений: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. Функция is_open(), не возвращает false когда клиент отключается. А когда он выходит, получается что функция рекурсивно себя ставит в очередь, и впустую тратятся ресуры Вопрос: Нормальный клиент должен закрывать сокет перед тем как выйти? Но все равно как узнать что клиент аварийно отключился и закрыть сокет? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2014, 09:55 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_Функция is_open(), не возвращает false когда клиент отключается. А когда он выходит, получается что функция рекурсивно себя ставит в очередь, и впустую тратятся ресуры Вопрос: Нормальный клиент должен закрывать сокет перед тем как выйти? Но все равно как узнать что клиент аварийно отключился и закрыть сокет? Функция is_open() не для этого. Чтобы узнать отключился ли клиент, надо проверять содержимое boost::system::error_code передаваемое параметром в обработчик. Я даже больше скажу, перед тем как что-либо делать в обработчике надо обязательно проверить есть ли ошибка или нет, а не так как у вас. Кроме того, в обработчике чтения/записи нужно объявлять также и параметр длины переданных данных, иначе вы не узнаете сколько получено, потому что не все асинх. функции читают ровно заданное кол-во данных. Схема такая: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2014, 15:04 |
|
||
|
Сокеты и библиотека boost::asio
|
|||
|---|---|---|---|
|
#18+
aybek_Вопрос: Нормальный клиент должен закрывать сокет перед тем как выйти? Но все равно как узнать что клиент аварийно отключился и закрыть сокет?1. Должен; shutdown, closesocket. 2. В момент закрытия клиентом (или сервером) сокета функция чтения recv / recvfrom (или ожидания события - select) сокета вернет SOCKET_ERROR, а фунция WSAGetLastError покажет конкретную причину, например WSAESHUTDOWN = The socket has been shut down. Тонкость - WSAGetLastError желательно (фактически - обязательно) вызывать сразу после функций работы с сокетом. Например, функция fwrite, вставленная между select и WSAGetLastError может исказить ошибку, возвращаемую WSAGetLastError. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2014, 15:28 |
|
||
|
|

start [/forum/topic.php?fid=57&msg=38530581&tid=2019751]: |
0ms |
get settings: |
10ms |
get forum list: |
12ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
67ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
47ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 169ms |

| 0 / 0 |
