Re: Howto find multiple servers using TCP



Here is how things work with UDP. You will have to create a UDP socket
(SOCK_DGRAM) instead of SOCK_STREAM. And since it's a connection-less
socket you don't call Connect. When a packet is sent using a UDP socket
(with SendTo) the OnReceive method gets called and you have to use
ReceiveFrom instead of Receive to get the data. Now there are some
differences between multicast and regular udp packets, multicast packets
only get routed to the computers that have subscribed to the multicast
address, and multicast can cross subnet boundries where UDP broadcasts
cannot.

Here is some sample code on how to create a sending and receiving multicast
socket, and how you might do your OnReceive method

BOOL LSSocket::CreateReceivingMulticastSocket(LPCTSTR strGroupIP, UINT
nGroupPort,DWORD &Error)
{
/* Create socket for receiving packets from multicast group */
if(!CAsyncSocket::Create(nGroupPort, SOCK_DGRAM,FD_READ))
{
Error = GetLastError();
return FALSE;
}

BOOL bMultipleApps = TRUE; /* allow reuse of local port if needed */
SetSockOpt(SO_REUSEADDR, (void*)&bMultipleApps, sizeof(BOOL),
SOL_SOCKET);

/* Join the multicast group */
m_mrMReq.imr_multiaddr.s_addr = inet_addr(strGroupIP); /* group addr */
m_mrMReq.imr_interface.s_addr = htons(INADDR_ANY); /* use default */
if(setsockopt(m_hSocket, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char FAR
*)&m_mrMReq, sizeof(m_mrMReq)) < 0)
{
Error = GetLastError();
return FALSE;
}

m_UDP = TRUE;
return TRUE;
}

BOOL LSSocket::CreateSendingSocket(UINT nTTL, BOOL bLoopBack,DWORD &Error)
{
if(!Create(0, SOCK_DGRAM)) // Create an unconnected UDP socket
{
Error = GetLastError();
return FALSE;
}

SetTTL(nTTL,Error); // Set Time to Live as specified by user

SetLoopBack(bLoopBack); // Enable/Disable Loopback
m_UDP = TRUE;
return TRUE;
}

void LSSocket::OnReceive(int nErrorCode)
{
char *Buffer = new char[30720]; //30K Buffer

memset(Buffer,0,30720);

int nRead = 0;
CString Address;
UINT Port = 0;
if (m_UDP)
{
nRead = CAsyncSocket::ReceiveFrom(Buffer,30720,Address,Port);
}
else
{
nRead = CAsyncSocket::Receive(Buffer,30720);
}

if (nRead == 30720)
{
TRACE("Socket Receive Overflow\n");
}

if (nRead != SOCKET_ERROR)
{
if (nRead)
{
ProcessMessage(Buffer,nRead,Address,Port);
}
}
else
{
CString Text;
Text.Format("Socket Receive Error number %d\n", GetLastError());
TRACE(Text);
}

delete [] Buffer;
CAsyncSocket::OnReceive(nErrorCode);
}


AliR.



"amccombs" <amccombs@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:2882BF79-94A3-4745-A2F8-E4108A0E5C70@xxxxxxxxxxxxxxxx
If I send out a broadcast packet on UDP, will my class that is derived
from
CAsyncSocket::OnReceive get called when data comes back?

(Other references seem to think that I have sit and wait for a reply at
the
next line after sending)


"AliR (VC++ MVP)" wrote:

No only UDP. But the Multicast is only there for the server finding and
then you would want to switch to a normal TCP socket once you find the
server.

AliR.


"amccombs" <amccombs@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:902C317D-01C5-4FE1-97D9-B93F04749975@xxxxxxxxxxxxxxxx
Can you multicast on TCP?


"AliR (VC++ MVP)" wrote:

I can't think of another way.

But if the server program is your program, then I have a suggestion.
I have a server that alot of clients connect to, and I really didn't
want
to
have to input the server address in every client. So what I did was I
used
a multicast socket to find the server. The server listens to traffic
on
a
particular multicast address, and when the clients want to find the
server
application, they would send a message (where are you) using a
multicast
socket with that particular address, the server would receive the
message
and send a reply (Here I am) with its IP address. Now if there are
more
than
one server, the client would get multiple "Here I am" replies. This
entire
process takes less than a second.

AliR.


"amccombs" <amccombs@xxxxxxxxxxxxxxxxxxxxxxxxx> wrote in message
news:129DBBB8-AD79-4588-91E0-0DF847EB11FB@xxxxxxxxxxxxxxxx
I have to search my subnet to look for servers that are listening on
port
30715. I am using one thread of a derived class of CAsyncSocket. I
am
using
CEvents with a 200 milisecond timeout, if there is no connection
within
the
200 miliseconds, then I know there is no serer. However searching
from
192.168.1.1 to 192.168.1.254 takes a long time. Is there a better
way?









.



Relevant Pages

  • Re: Howto find multiple servers using TCP
    ... int CAsyncSocket::SendTo( ... When a packet is sent using a UDP socket ... differences between multicast and regular udp packets, ... But if the server program is your program, ...
    (microsoft.public.vc.mfc)
  • Re: Howto find multiple servers using TCP
    ... OnReceive ReceiveFrom section, what would you do? ... When a packet is sent using a UDP socket ... differences between multicast and regular udp packets, ... But if the server program is your program, ...
    (microsoft.public.vc.mfc)
  • Re: Howto find multiple servers using TCP
    ... But you can still use asynchronous sockets for UDP. ... Obviously, this only works when you have a possible multicast router, or no router at all; ... When a packet is sent using a UDP socket ... But if the server program is your program, ...
    (microsoft.public.vc.mfc)
  • Re: SetSockOpt with SO_REUSEADDR parameter
    ... happening is that you are throwing away the old socket and replacing it with the new ... I write a server application to send real-time video frame to client. ... Because I will send real-time video frame, I use UDP socket. ...
    (microsoft.public.vc.mfc)
  • Re: Error binding socket: address already in use
    ... SOCK_DGRAM, IPPROTO_UDP), leaves the socket in an unclosed state. ... If you are seeing UDP sockets remain open when you kill a server make ... Additional note on REUSEADDR: The standard semantics of REUSEADDR on a ... UDP socket is to allow several sockets to bind to the same address ...
    (Linux-Kernel)