Братья по разуму, помогите разобраться. Не улавливаю суть. Когда мы создаем "слушающий" сокет, в переменную sockaddr.inet_addr мы помещаем константу INADDR_ANY (INADDR_ANY equ 000000000h (windows.inc)). 1.Что из себя представляет полученный сокет в привычном формате ? 0.0.0.0:port ? Для наглядности, хотелось-бы посмотреть на это в Олли... 2. Что нужно сделать, чтобы увидеть этот сокет в привычном формате ? После этого, функцией accept, мы разрешаем входящее соеденение, получая при этом хендл сокета, через который будут поступать данные. 3. Вот тут непонятно. Порт мы слушаем одним сокетом, данные получаем через другой, при этом, первый еще и сообщеня шлет, что данные читаются...Недогоняю... Он что, их перенаправляет, что-ли ??? 4. Чем будут различаться эти сокеты? IP адресами ? Портами ? 5. Что будет представлять из себя созданный сокет в привычном формате и где на это можно поглазеть ? Вот такой бардак у меня в башке. Там еще куча вопросов, но пока нужно хоть на эти, ответы получить. Без стакана не разобраться. Стакан с меня за ответы
Да, по крайней мере, так его показывают сетевые мониторы. В олли вряд ли получится посмотреть, разве что в программе получить адрес и порт по сокету. Я бы посоветовал почитать соответствующую книгу об организации TCP и сетевом программировании. Да, создаётся два сокета: первый, слушающий, этим и занимается — ждёт подключений от клиентов на определённых адресе и порту, при подключении клиента "уведомляет" программу, а ты уже вызовом accept создаёшь второй сокет, с которым уже и общается клиент; первый в этом общении уже не учавствует — он ждёт других подключений. а) типом (см. выше); б) портами (сокет, созданный accept'ом будет иметь тот же адрес, но другой порт, из пространства незарезервированных портов. n.n.n.n:p, где n.n.n.n - адрес сервера, а p - выделенный под соединение сокет. Посмотреть в сетевом мониторе или получить его в программе.
Структуру данных, в одном из полей которой (ну почти) находится структура sockaddr_in, заполненая ствоими значениями (0x00000000h, port), так что, ничего особенного ты там не увидишь. Давай по порядку. Сначала мы создаём сокето вызовом s = socket(...); в ядре инициализируется структура сокета (domain, type, protocol) и возвращается дескриптор сей структуры. Затем мы делаем bind(s, sockaddr), тем самым говоря ядру что мы хотим связать наш сокет с определённым адресом и портом. Причём биндить можно и обычные сокеты, чтобы задать адрес и порт исходящего соединения; но это обычно не делается (а нужно ли? редко). Для слушающего же сокета это делается для того, чтобы сервер висел на строго определённом порту (скажем, 80). Если в sockaddr.port задать 0, то система выберет случайный порт(как тут прикажешь клиентам коннектиться к серверу? какой порт им выбирать? А вот именно в следующем вызове происходит самое интересное - мы делаем listen(s, 100), говоря ядру тем самым, что это не коннект-сокет, а слушающий сокет, то есть он сам будет принимать подключения. В ядре это выглядит примерно так: через один из указателей структуры сокета создаётся список (или очередь) свободных сокетов в которые и будут приходить соединения от клиентов (размер очереди задаётся через второй (ну почти, системы по-разному обрабатывают этот параметр, кто-то умножает на коэффициент, кто-то просто передает как есть) параметр listen, в данном случае это 100). Далее, после того как подключился один из клиентов (рукопожатие прошло), сокет этот перемещается в дугую очередь - очередь завершённых соединений. Причем указатели на эти очереди находятся всё в том же слушающем сокете. Именно оттуда (из второй очереди) мы его забираем функцией accept(). Но это так, введение, тебе же нужно почитать к примеру R. Stivens, TCP Illustrated(vol.2) The Implementation, Глава 15 Socket Layer
Кстати, всё вышесказаное касается TCP. Если брать в расчет и UDP, то там никаких connect-accept нету, ты просто создаешь сокет и биндишь его с соответствующим адресом и все. Дальше, для отправки сообщения вызываешь sendto предварительно заполнив структуру sockaddr_in адресом получателя, а для получения вызываешь recvfrom при этом структура sockaddr_in будет заполнена адресом отправителя.
Если брать в расчёт и RAW-сокеты... Если брать в расчёт и SCTP... Если брать... Если давать... Если...
Ладно вам, горячие финские парни =) Тогда, скажите лучше, как указать протокол по которому будет происходить передача ? По какому протоколу она будет проходить, если не указвать протокол ?
Протокол, обеспечивающий передачу данных на низком уровне и управление соединением, ты указываешь как третий параметр функции socket() - IPPROTO_TCP ну и так далее. Протокол, описывающий формат данных на высоком уровне (например HTTP) ты реализуешь самостоятельно, winsock этим не занимается
По всей видимости это заблуждение, которое чуть не стало моим. Далее цитата из книги Йон'a Снейдер'a "Эффективное программирование TCP/IP" Ибо, доверяй, но поверяй !
Aspire Хм, действительно. Я спутал с портом клиента, в случае, если он не привязывается специально к определённому. То есть, если привязать адрес и порт клиента, то повторное соединение к серверу не удастся из-за коллизии с существующим сокетом?