socket question: how to use sendto and recvfrom based on the same multicast address



I'm building a multicast UDP program which need to send data to one
multicast address and receive other data from others on the samd
multicast address. I always find that I can't send and receive at the
same time.
The following is my test code. First, create a socket for receiving,
set SO_REUSEADDR, bind it, add multicast membership and then receive
data from recvfrom. This works find. Then I create a socket for
sending, set SO_REUSEADDR, bind it and use sendto to send data. This
failed and the error message is 10047 WSAEAFNOSUPPORT, I don't what I
can do. What's the problem? How can I send and receive data while
binding to one multicast address? Need your help, Thanks!


--------------------------------------------------------------------
#include <winsock2.h>
#include <winsock.h>
#include <stdio.h>
#include <windows.h>
#include <ws2tcpip.h >
#include <stdlib.h>
#define DESTCAST "233.0.0.3"
#define DESTPORT 5150


int WINAPI WinMain (
HINSTANCE hInstance, // Handle to the current instance
HINSTANCE hPrevInstance,// Handle to the previous instance
LPTSTR lpCmdLine, // Pointer to the command line
int nCmdShow)
{
char szMessage[30]="hahahaa\n";
int sockrcv,socksnd;
struct sockaddr_in local_sin,dest_sin,recv_sin;
WSADATA wsd;
int reuseaddress;
struct ip_mreq mreq;
int iRecvLen;

/* Init WinSock2.2 */
if(0!=WSAStartup( WINSOCK_VERSION,&wsd))
{
printf("WSAStartup() failed!\n");
return 0;
}
/* Create socket of DGRAM type, and reconfig it in miniport driver
*/
if((sockrcv=socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("socket failed with:%d\n",WSAGetLastError());
WSACleanup();
return 0;
}

reuseaddress = 1;
if(setsockopt(sockrcv,
SOL_SOCKET,
SO_REUSEADDR,
(char FAR *)&reuseaddress,
sizeof (reuseaddress)) == SOCKET_ERROR)
{
printf("setsockopt SO_REUSEADDR failed:%d\n",WSAGetLastError());
closesocket(sockrcv);
WSACleanup();
return 0;
}

/*We have to bind in CE*/
local_sin.sin_family = AF_INET;
local_sin.sin_port = htons(DESTPORT);
local_sin.sin_addr.s_addr = htonl (INADDR_ANY);

if (bind (sockrcv,
(struct sockaddr FAR *) &local_sin,
sizeof (local_sin)) == SOCKET_ERROR)
{
printf("bind failed:%d\n",WSAGetLastError());
closesocket (sockrcv);
return FALSE;
}

mreq.imr_interface.s_addr=INADDR_ANY;
mreq.imr_multiaddr.s_addr=inet_addr(DESTCAST);//???
if (setsockopt (sockrcv,
IPPROTO_IP,
IP_ADD_MEMBERSHIP,
(char FAR *)&mreq,
sizeof (mreq)) == SOCKET_ERROR)
{
printf("setsockopt IP_ADD_MEMBERSHIP failed:%d
\n",WSAGetLastError());
closesocket(sockrcv);
WSACleanup();
return 0;
}

dest_sin.sin_family = AF_INET;
dest_sin.sin_port = htons(DESTPORT);
dest_sin.sin_addr.s_addr = inet_addr (DESTCAST);

printf("recvfrom:");
iRecvLen = sizeof (recv_sin);
if (recvfrom (sockrcv,
szMessage,
100,
0,
(struct sockaddr FAR *) &recv_sin,
&iRecvLen) == SOCKET_ERROR)
{
printf ("recvfrom failed! Error: %d",WSAGetLastError ());
closesocket (sockrcv);
return FALSE;
}
else
{
printf("Success!!!!\n");
}

Sleep(1000);


if((socksnd=socket (AF_INET, SOCK_DGRAM, 0)) == INVALID_SOCKET)
{
printf("socket failed with:%d\n",WSAGetLastError());
WSACleanup();
return 0;
}

reuseaddress = 1;
if(setsockopt(socksnd,
SOL_SOCKET,
SO_REUSEADDR,
(char FAR *)&reuseaddress,
sizeof (reuseaddress)) == SOCKET_ERROR)
{
printf("setsockopt SO_REUSEADDR failed:%d\n",WSAGetLastError());
closesocket(socksnd);
WSACleanup();
return 0;
}


if (bind (socksnd,
(struct sockaddr FAR *) &local_sin,
sizeof (local_sin)) == SOCKET_ERROR)
{
printf("bind failed:%d\n",WSAGetLastError());
closesocket (socksnd);
return FALSE;
}

if (sendto (socksnd,
szMessage,
strlen (szMessage) + 1,
0,
(struct sockaddr FAR *) &dest_sin,
sizeof (dest_sin)) == SOCKET_ERROR)
{
printf ("sendto failed! Error: %d",WSAGetLastError ());
closesocket (socksnd);
return FALSE;
}
else
printf("Sending data succeeded!");
Sleep(1000);

// Disable receiving on Sock before closing it.
shutdown (sockrcv, 0x00);
shutdown (socksnd, 0x00);
// Disable sending on Sock before closing it.
shutdown (sockrcv, 0x01);
shutdown (socksnd, 0x01);
// Close Sock.
closesocket (socksnd);
closesocket (sockrcv);
return TRUE;
}

.



Relevant Pages


Loading