У меня проблема с сокетом c ++.
Я использую CAsyncSocket из MFC, к которому я хочу присоединиться к группе многоадресной рассылки.
Также мне нужно иметь несколько слушателей в этой группе, и вот тут я попал в беду.
Я нашел несколько примеров в Интернете, но, похоже, это не работает.
Вот мой код:
//create socket on port 17233
BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ);
//set reuse socket option
BOOL bMultipleApps = TRUE;
bRet = SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);
//join multicast group
ip_mreq m_mrMReq; // Contains IP and interface of the host group
m_mrMReq.imr_multiaddr.s_addr = inet_addr((LPCSTR)"224.30.0.1"); /* group addr */
m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */
int uRes =setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR *)&m_mrMReq, sizeof(m_mrMReq));
Нет ошибок при запуске.
Но когда я пытаюсь запустить другой экземпляр приложения, он не может создать новый сокет на этом порту, потому что порт используется.
Я сделал это в C #, и он работал нормально, как это:
IPEndPoint ipep = new IPEndPoint(IPAddress.Any, port);
s.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
s.Bind(ipep);
IPAddress ip = IPAddress.Parse(mcastGroup);
s.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(ip, IPAddress.Any));
s.SetSocketOption(SocketOptionLevel.IP,SocketOptionName.MulticastTimeToLive, int.Parse("1"));
Так что, если какое-либо тело увидит проблему с моим кодом или у меня есть несколько советов, я с радостью буду благодарен.
РЕДАКТ. 1:
Является ли CAsyncSocket TCP-сокетом?
РЕДАКТИРОВАТЬ 2:
После прочтения Могут ли два приложения прослушивать один и тот же порт?
Я думаю, что сделал путаницу. Мне нужен многоадресный UDP-порт, к которому может обращаться несколько приложений, используя SO_REUSEADDR
Редактировать для уточнения:
BOOL bRet = Create(17233,SOCK_DGRAM, FD_READ)
Создает сокет UDP и привязывается к порту 17223.
Чтобы SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);
работал, вам нужно установить его перед привязкой, как сказал @Hasturkun.
Окончательный рабочий код выглядит так:
BOOL bRet = Socket(SOCK_DGRAM, FD_READ);
if(bRet != TRUE)
{
UINT uErr = GetLastError();
std::cout<<"Error:"<<uErr<<std::endl;
return FALSE;
}else{
std::cout<<"Create sock: OK"<<std::endl;
}
//add reuse
BOOL bMultipleApps = TRUE; /* allow reuse of local port if needed */
SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL), SOL_SOCKET);
//bind
bRet = Bind(17233, NULL);
if(bRet != TRUE)
{
UINT uErr = GetLastError();
std::cout<<"Error(BIND):"<<uErr<<std::endl;
}else{
std::cout<<"BIND sock: OK"<<std::endl;
}
Спасибо
Gabriel
;