Официальный форум СВД Встраиваемые Системы
04 Декабря, 2016, 09:07:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Войти
 
 
 Сайт СВД ВС  Начало   Помощь Поиск Войти Регистрация  
Страниц: [1]   Вниз
  Печать  
Автор Тема: Немонопольное использование bind  (Прочитано 626 раз)
Роман
Интересующийся

Сообщений: 9

Gravatar


« : 28 Августа, 2015, 15:49:14 »

Добрый день!
QNX6.5.0 sp1
При попытке bind с одинаковым адресом и портом выдает ошибку "Address already in use".
Код:
struct sockaddr_in snd_addr;
snd_addr.sin_family = AF_INET;
#ifdef WIN32
        int addr_len = sizeof( struct sockaddr_in );
        snd_addr.sin_addr.S_un.S_addr =
qToBigEndian< quint32 >( m_hostLocal.toIPv4Address() );
#else // #ifdef WIN32
        socklen_t addr_len = sizeof( struct sockaddr_in );
        snd_addr.sin_addr.s_addr =
qToBigEndian< quint32 >( m_hostLocal.toIPv4Address() );
#endif // #ifdef WIN32
snd_addr.sin_port = qToBigEndian< quint16 >( m_uiLocalPort );

int opt_val = 1;
if ( ::setsockopt( snd_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* )&opt_val, sizeof( opt_val ) ) != 0 )
{
     qDebug()
                << "CUdpReceiverExt::initSock: SO_REUSEADDR error"
#ifdef WIN32
                << GetLastError();
#else // #ifdef WIN32
                << strerror( errno );
#endif // #ifdef WIN32
}

opt_val = 1;
if ( ::setsockopt( snd_sock, SOL_SOCKET, SO_REUSEPORT, ( const char* )&opt_val, sizeof( opt_val ) ) != 0 )
{
         qDebug()
                         << "CUdpReceiverExt::initSock: SO_REUSEPORT error"
        #ifdef WIN32
                        << GetLastError();
        #else // #ifdef WIN32
                        << strerror( errno );
        #endif // #ifdef WIN32
}

opt_val = 1;
if ( ::setsockopt( snd_sock, SOL_SOCKET, SO_BROADCAST, ( const char* )&opt_val, sizeof( opt_val ) ) != 0 )
{
            qDebug()
                << "CUdpTransmitter::initSock: SO_BROADCAST "
#ifdef WIN32
                << GetLastError();
#else // #ifdef WIN32
                << strerror( errno );
#endif // #ifdef WIN32
}

if( ::bind( snd_sock, ( const struct sockaddr* )&snd_addr, addr_len ) != 0 )
{
qDebug()
<< "CUdpTransmitter::setBind: bind error "
#ifdef WIN32
                << GetLastError();
#else // #ifdef WIN32
                << strerror( errno );
#endif // #ifdef WIN32
}
else
{
      qDebug()
                << "CUdpTransmitter::setBind:"
                << "successfully binded to"
                << m_hostLocal.toString(  )
<< ":"
<< m_uiLocalPort
                << " remote address"
                << m_hostRemote.toString()
                << ":"
                << m_uiRemotePort;
}



На Suse 13.2 все работает.
« Последнее редактирование: 28 Августа, 2015, 17:01:34 от Роман » Записан
deadarcher
Пользователь

Сообщений: 61


« Ответ #1 : 29 Августа, 2015, 12:47:48 »

Мне всегда казалось, что удачный bind() для сокетов с одинаковым адресом и портом, возможен лишь для разнотиповых сокетов, как-то: один сокет потоковый, другой дэйтаграмный.  Wink
Тоже интересно, подожду послушаю, что гуру скажут.
Записан
Андрей Панченко
Сотрудник СВД ВС
Пользователь

Сообщений: 76



WWW
« Ответ #2 : 03 Сентября, 2015, 13:07:33 »

Роман, я проверил bind с одинаковым адресом и портом в своей тестовой программе, и у меня не воспроизвелась ошибка, т.е. bind успешно проходит с несколькими одновременно работающими программами. Если вы ещё не решили проблему, просьба подготовить минимальный собирающийся пример.
Записан

Сотрудник СВД Встраиваемые Системы
Роман
Интересующийся

Сообщений: 9

Gravatar


« Ответ #3 : 03 Сентября, 2015, 13:09:13 »

Хорошо. Вытащу кусок, протестирую и выложу сюда.
Записан
deadarcher
Пользователь

Сообщений: 61


« Ответ #4 : 05 Сентября, 2015, 11:47:30 »

Андрей, а можете немного пояснить механизм - получается что при получении TCP/IP стэк должен будет доставить данные во все слушающие ("забинденные") сокеты ? В случае датаграммных сокетов это ещё как-то понятно, а как тогда в случае потоковых сокетов ?
Записан
Андрей Панченко
Сотрудник СВД ВС
Пользователь

Сообщений: 76



WWW
« Ответ #5 : 07 Сентября, 2015, 13:36:19 »

Для UDP multicast и broadcast данные будут доставляться во все слушающие сокеты, unicast только при использовании опции reuseport_unicast для io-pkt.
Для TCP, очевидно, соединение установится и дальнейший обмен будет идти для последнего "забинденного" сокета.
Записан

Сотрудник СВД Встраиваемые Системы
deadarcher
Пользователь

Сообщений: 61


« Ответ #6 : 07 Сентября, 2015, 18:31:04 »

Спасибо, Андрей. Буду знать  Smiley
Записан
Роман
Интересующийся

Сообщений: 9

Gravatar


« Ответ #7 : 21 Сентября, 2015, 10:48:13 »

Необходимо установить SO_REUSEADDR. Все работает Grin
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  

Powered by MySQL Powered by PHP © 2002-2016 СВД Встраиваемые Системы.
При использовании материалов сайта ссылка на forum.kpda.ru обязательна.

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines | © Aiwan. Kolobok smiles | Sitemap
Valid XHTML 1.0! Valid CSS!
Сайт СВД ВС

В последний раз google посещал эту страницу 17 Ноября, 2016, 02:31:03