Уважаемые, Скажите, можно ли вообще с одним сокетом работать из разных потоков? Вернее не так. То что можно - я уже понял. Не будет ли логических ошибок при, например, одновременном вызове send двумя и более потоками? Пример: если я в одном потоке вызываю send, он начинает выполнение, тут другой поток тоже вызывает send. Как адресату придут данные? Сначала от первого вызова, а затем от второго? Или будет некая "вставка" данных? Сколько раз мне надо будет вызвать recv, чтобы получить все даные от 2х потоков клиента (буфер достаточно большой)? Еще пример: один поток заблокирован ф-ей recv, а тут другой поток вызвал send для того же сокета. Речь идет о блокирующих TCP сокетах. Хотя про UDP тоже интересно. Да и не только про winsock, но и про обычные бэркли. Как работать - не ясно. Копал MSDN - но четкого ответа не нашел.
Спасибо за ответы. Понял, одновременные вызовы send буду мьютексами защищать. А вот как быть, если один поток заблокирован вызовом recv, а другому надо вызвать send? Можно слать данные оставить? Или ждать, пока вернется recv? Пока я бы сделал так: 1 сокет 2 мьютекса первый защищает чтение, второй - запись. Так нормально?
Сокет имеет отделные буферы для отправки и приема. Пока recv ожидает данных в приемном буфере, можено делать send для буфера отправки. Ты лучше скажи, что ты хочешь сделать этими несколькими потоками и одним сокетом. А еще лучше, купи/скачай и почитай книгу "UNIX. Разработка сетевых приложений".
Спасибо. Да вот писал уже в одном топике, что хочу сделать приложение для отладки работы другого софта (клиент-сервер по TCP). Часто такие задачи бывают по работе. ПО встает в канал между клиентом и сервером. Логгирует траффик, измеряет задержки. Одним потоком читать и слать из 2х сокетов с помощью select у меня не получилось. Сделал в 2 потока на одно отлаживаемое соединение (2 сокета). Изначально после коннекта оба ждут в recv. Как только данные появились у одного из них - поток пишет в соответствующий сокет и логгирует все что написал. Вот меня и смущал факт работы 2х потоков с одним сокетом. Теперь стало ясно. Вопрос остался с accept. Если клиент делает connect на сервер, мое ПО сначала должно сделать accept клиента, а потом уже сделать connect на реальный сервер. Т.е. в любом случае клиенту удастся подключиться, даже если не поднят сервер. А это нарушает логику, и "отлаживанием" такой процесс уже нельзя назвать, т.к. в реале будет иначе. Вот как бы узнать, ждут меня на другом конце, или нет. По поводу "UNIX. Разработка сетевых приложений". Я пишу под винды. Слашал, что MS портировала сокеты Бэркли. Но все-равно вопрос остался: одинаково ли программирование сокетов (TCP, UDP, не raw) в UNIX и Windows?? + неясность вводит наличие у MS разных версий winsock.
Стопроцентно врят ли можно что-то сделать, но слёту два варианта есть: - в своем коде гонять в цикле connect/disconnect, обновляя флаг доступности сервера, который проверяешь при accept'e клентов. - однажды подключиться к серверу, настроив keepalive - если сервер станет недоступен, снова выставляем флаг, который проверяем при accept'e клентов. Базовые концепции одинаковы на всех осях, как-то: буферы для сокетов, поддерживаемые опции, структуры адресов и проч. Всё это, так или иначе, различается в реализации, но смысл и способ использования тот же.
Еще вариант, пока что самый правильный: - как-то узнаем, что пришел клиент, но accept пока что не делаем (а-ля select). - делаем коннект к серверу. - если коннект есть, то делаем accept клиента, связываем сокеты и работает как нужно, если коннекта нет, то делаем accept клиента и сразу же закрываем его сокет.
Да, это действительно самый правильный вариант. Тогда ПО не нарушит логику работы. Вопрос теперь - как узнать что пришел клиент без accept(). Буду читать доки. Спасибо.
Можно банально и проще всего через select(). В книге что выше есть примеры и объяснения. Полистай еще Network Programming for Microsoft® Windows®, Second Edition. Тоже неплохая книга.
Если уж быть совсем точным и честным, то клиент подключится нормально до того как ты сделаешь accept(). Подробнее почитай WASM.BEGINNERS.
А простыми tcpdump/wireshark нельзя? Размеры пакетов и временные интервалы они показывают - импортировать куда-нить и проанализировать.
Да можно, но не очень. Бывает что несколько экземпляров приложения работают. Причем каждое коннектится то к одному, то к другому серверу. Да и сам давно хотел уже написать какое-нибудь многопоточное приложение с использованием сокетов. Сколько можно то уже... Каждый раз в доки лезу.