Работа с сокетами
Теперь мне надо сделать програму которая запускается на 2 компютерах, и с каждого компютера на другой можна отправлять сообщения, типа чата.
Вопрос: будущая архитектура приложения?
На каждом компе клиент-сервер и сервер 1 слушает клиента 2 с другого компютера? или как?
Каким образом одна программа может реализовать эту архитектуру?
Вот, почитайте что такое "архитектура клиент-сервер". Вкратце (применительно к программной реализации): есть 2 программы - одна сервер, другая - клиент. Запускаем сервер на одном компьютере, на другом запускаем клиент и подключаемся к серверу (который запущен на первом компьютере). Всё, теперь можно обмениваться сообщениями. Это так называемая "централизованная" сеть. Т.е. у вас один сервер и все компьютеры подключаются только к нему.
Если же вы хотите децентрализованную сеть (т.е. чтобы каждый компьютер мог подключиться к любому другому), то вам необходимо запускать и сервер и клиент на одном компьютере (желательно совместить эти 2 программы). Т.е. получается, что каждый компьютер в сети играет роль как клиента (мы подключаемся), так и сервера (к нам подключаются).
На самом деле, серверу абсолютно всё равно, кого "слушать", потому что сервер слушает не клиента, а определенный порт, по которому к нему должны подключаться клиенты.
в основе лежит принцип многопоточности (почитайте обязательно - WinAPI Threads).
Если ваше приложение имеет графический интерфейс, то по событию "создание окна", создаете отдельный поток, который будет иметь функционал сервера (т.е. слушать порт и обрабатывать соединения).
В основном же потоке (тот, который обрабатывает интерфейс), реализуете функционал клиента. Т.е. если, например, у вас есть кнопка "подключиться", то назначаете на событие "OnClick" этой кнопки, подключение к серверу.
Простейший пример работы с потоками - пишете ф-цию в которой выполняется какое-либо действие, потом вызываете ф-цию WinAPI CreateThread, указав в одном из параметров адрес вашей ф-ции. После этого Windows создает вам поток (или по-другому "нить"), в котором выполняет вашу ф-цию.
В вашем случае, ф-ция должна будет "слушать" порт и обрабатывать подключения.
Нужна идея). Пытаюсь сделать кросплатформенную (понятно что не добится полностью, ну максимально платформо-независимую) реализацию клиентского сокета, тобеж на чистом С++. Проблема в том, что я не могу найти инфу по реализации клиентной части поддерживающей асинхронную работу при множественных параллельных запросах к серверу.
На сколько я понял, данную структуру поддерживает winsock2.h через WSAAsyncSelect, но приставка win смущает поодержкой только виндой.
Еще вариант создавать отдельные потоки... Но тут бы мне подкинуть общую архитектуру, как это будет правильно организовать.
Нужна идея). Пытаюсь сделать кросплатформенную (понятно что не добится полностью, ну максимально платформо-независимую) реализацию клиентского сокета, тобеж на чистом С++. Проблема в том, что я не могу найти инфу по реализации клиентной части поддерживающей асинхронную работу при множественных параллельных запросах к серверу.
На сколько я понял, данную структуру поддерживает winsock2.h через WSAAsyncSelect, но приставка win смущает поодержкой только виндой.
Еще вариант создавать отдельные потоки... Но тут бы мне подкинуть общую архитектуру, как это будет правильно организовать.
http://forum.sources.ru/index.php?showtopic=255571
ну и в сторону QT посмотреть
ну и в сторону QT посмотреть
Угу пасиб сейчас пошукаю
Под асинхронной работой я подразумеваю множественные одновременные запросы к одному или нескольким серверам, не блокирующие юайный поток
а сокетов то сколько будет? на каждый сервер свой или все через один?
Вот это я и хотел уточнить у знающих людей, каким образом лучше выстроить такое взаимодействие
Тут вопрос скорее на каком уровне эту асинхронность вам хочется видеть. Её можно организовать руками, используя неблокирующие сокеты с ожиданием готовности сокетов на чтение/запись через допустим select (вариант с блокирующими сокетами в разных потоках я так понимаю вы итак не рассматриваете). Вполне себе асинхронный обмен запросами получится.
Или второй способ использовать POSIX aio функции (aio_read, aio_write, ...) или же WSAEventSelect/WSAAsyncSelect + обработка сообщений или событий в винде.
Тут данные будут отправляться асинхронно уже для программста в ядре и вас лишь известят событием, когда отправка, или прием данных будут завершены.
В данном случае реализация под разные платформы будет отличаться и должна допустим разруливаться ifdef-ами в коде.
Собственно в том и вопрос: какая модель вам подойдет больше - видно только вам.
Ну задача поставлена именно изобретать)
А по поводу реализации, я рассматриваю два варианта развития:
1. выделять новый сокет для сервера. (это будет около 8) и последовательно рулить запросами, ожидая когда предыдущий будет обработан. На мой взгляд это будет несколько долго, если на один сервер будет лететь их сразу пачкой.
2. вариант под каждый запрос создавать сокет. Думаю что будет быстрее. Но как-то по идеологическим причинам мне кажется что метод не айс:)
Как ты себе представляешь один? =)
1. выделять новый сокет для сервера. (это будет около 8) и последовательно рулить запросами, ожидая когда предыдущий будет обработан. На мой взгляд это будет несколько долго, если на один сервер будет лететь их сразу пачкой.
Если честно нифига не понял что же тут хотите сделать. ))
Если честно нифига не понял что же тут хотите сделать. ))
Эммм...для каждого сервера создать отдельный сокет, выстроить очередь запросов, и все запросы к серверу шуровать через этот сокет, последовательно. Один отработал - следующий... Ну как-то так)) Это пока теория, может и не совместима с практикой:)
В люббом случае на каком либо уровне будет некоторая последовательность. Но работать можно при этом вполне асинхронно и не дожидаясь резльата. Яж вон там уже расписал два способа.
Под каждый запрос сокет создавать - это совсем абсурд. темболее, что всеравно же вам придется блочиться на accept-e серверной стороны, для ожидания этих сокетов. Или же мультиплицировать неблокирующий accept вместе с остальными неблокирующими сокетами через select. )
Пасиб за совет, вроде стало проясняться:)
Буду играться)
Фуйню сморозил... согласен
В любом случае, как только соединение открыто, различие "клиент-сервер" теряется и любая сторона может как отправлять данные, так и получать. Кстати, на к сокету есть возможность присобачить event, который будет включаться, как только на сокет пришли данные, и этот event можно использовать так, что вообще многопоточность не понадобится - в UI-потоке вместо GetMessage использовать MsgWaitForMultipleObjects. Впрочем, если обработка сетевых сообщений занимает длительное время (и особенно если комп многопроцессорный/многоядерный), то лучше запускать отдельные потоки.