looks like a problem with SO_REUSEADDR exists in CYGWIN for all windows with support for "Enhanced socket security" (see http://msdn.microsoft.com/en-us/library/ms740621(VS.85).aspx <http://www.google.com/url?sa=D&q=http://msdn.microsoft.com/en-us/library/ms740621%28VS.85%29.aspx&usg=AFQjCNF9bXOmPTwYjiP37Xdq2xRAYNXfWg>)

i'am trying to start multimple simultaneous UDP listeners for a multicast packets on a single machine (reuse same address and port with SO_REUSEADDR)

i've done such tests with cygwin 1.7 beta in windows vista, server 2008, 7 environment - all with no success, i.e. i can't start more than one listener (i see an error message Address already in use in bind())!
in windows xp all works as expected!

i'll show some samples to demonstrate this:
=================listener.c========================
#include <sys/types.h>
#ifndef __MINGW32__
       #include <sys/socket.h>
       #include <arpa/inet.h>
       #include <netinet/in.h>
#else
       #include <winsock2.h>
       #include <ws2tcpip.h>
#endif
#include <stdio.h>
#include <stdlib.h>
struct sockaddr_in localSock;
struct ip_mreq group;
int sd;
int datalen;
char databuf[1024];
int main(int argc, char *argv[])
{
       struct sockaddr_in sender_addr;
       int sender_addr_size = sizeof(sender_addr);
#ifdef __MINGW32__
       WSADATA wsadata;
       if (WSAStartup(MAKEWORD(2,2), &wsadata) == SOCKET_ERROR) {
               printf("can't WSAStartup\n");
               exit(1);
       }
#endif
       /* Create a datagram socket on which to receive. */
       sd = socket(AF_INET, SOCK_DGRAM, 0);
       if(sd < 0)
       {
               printf("Opening datagram socket error %d\n", sd);
               exit(1);
       }
       printf("Opening datagram socket....OK.\n");
       /* Enable SO_REUSEADDR to allow multiple instances of this */
       /* application to receive copies of the multicast datagrams. */
       {
               int reuse = 1;
if(setsockopt(sd, SOL_SOCKET, SO_REUSEADDR, (char *)&reuse, sizeof
(reuse)) < 0)
               {
                       perror("Setting SO_REUSEADDR error");
                       close(sd);
                       exit(1);
               }
               printf("Setting SO_REUSEADDR...OK.\n");
       }
       /* Bind to the proper port number with the IP address */
       /* specified as INADDR_ANY. */
       memset((char *) &localSock, 0, sizeof(localSock));
       localSock.sin_family = AF_INET;
       localSock.sin_port = htons(4321);
       localSock.sin_addr.s_addr = INADDR_ANY;
       if(bind(sd, (struct sockaddr*)&localSock, sizeof(localSock)))
       {
               perror("Binding datagram socket error");
               close(sd);
               exit(1);
       }
       printf("Binding datagram socket...OK.\n");
       /* Join the multicast group 226.1.1.1 on the local 203.106.93.94 */
       /* interface. Note that this IP_ADD_MEMBERSHIP option must be */
       /* called for each local interface over which the multicast */
       /* datagrams are to be received. */
       group.imr_multiaddr.s_addr = inet_addr("226.1.1.1");
group.imr_interface.s_addr = INADDR_ANY;//inet_addr("203.106.93.94");
       if(setsockopt(sd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&group,
sizeof(group)) < 0)
       {
               perror("Adding multicast group error");
               close(sd);
               exit(1);
       }
       printf("Adding multicast group...OK.\n");
       /* Read from the socket. */
       datalen = sizeof(databuf);
       while(1)
       {
               printf("Receiving...\n");
               if(recvfrom(sd, databuf, datalen, 0, (struct sockaddr *)
&sender_addr, &sender_addr_size) < 0)
               {
                       perror("Reading datagram message error");
                       close(sd);
                       exit(1);
               }
               else
               {
                       printf("Reading datagram message...OK.\n");
printf("The message from multicast server is: \"%s\"\n", databuf);
               }
       }
       return 0;
}

===============================================================
============send.c==============================================
/* Send Multicast Datagram code example. */
#include <sys/types.h>
#ifndef __MINGW32__
       #include <sys/socket.h>
       #include <arpa/inet.h>
       #include <netinet/in.h>
#else
       #include <winsock2.h>
       #include <ws2tcpip.h>
#endif
#include <stdio.h>
#include <stdlib.h>
struct in_addr localInterface;
struct sockaddr_in groupSock;
int sd;
char databuf[1024] = "Multicast test message!";
int datalen = sizeof(databuf);
int main (int argc, char *argv[ ])
{
#ifdef __MINGW32__
       WSADATA wsadata;
       if (WSAStartup(MAKEWORD(2,2), &wsadata) == SOCKET_ERROR) {
               printf("can't WSAStartup\n");
               exit(1);
       }
#endif
       /* Create a datagram socket on which to send. */
       sd = socket(AF_INET, SOCK_DGRAM, 0);
       if(sd < 0)
       {
               perror("Opening datagram socket error");
               exit(1);
       }
       printf("Opening the datagram socket...OK.\n");
       /* Initialize the group sockaddr structure with a */
       /* group address of 225.1.1.1 and port 5555. */
       memset((char *) &groupSock, 0, sizeof(groupSock));
       groupSock.sin_family = AF_INET;
       groupSock.sin_addr.s_addr = inet_addr("226.1.1.1");
       groupSock.sin_port = htons(4321);
       /* Disable loopback so you do not receive your own datagrams.
       {
               char loopch = 0;
if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_LOOP, (char *)&loopch,
sizeof(loopch)) < 0)
               {
                       perror("Setting IP_MULTICAST_LOOP error");
                       close(sd);
                       exit(1);
               }
               printf("Disabling the loopback...OK.\n");
       }
       */
       /* Set local interface for outbound multicast datagrams. */
       /* The IP address specified must be associated with a local, */
       /* multicast capable interface. */
       localInterface.s_addr = INADDR_ANY;
       if(setsockopt(sd, IPPROTO_IP, IP_MULTICAST_IF, (char *)
&localInterface, sizeof(localInterface)) < 0)
       {
               perror("Setting local interface error");
               exit(1);
       }
       printf("Setting the local interface...OK\n");
       /* Send a message to the multicast group specified by the*/
       /* groupSock sockaddr structure. */
       /*int datalen = 1024;*/
       if(sendto(sd, databuf, datalen, 0, (struct sockaddr*)&groupSock,
sizeof(groupSock)) < 0)
       {
               perror("Sending datagram message error");
               exit(1);
       }
       printf("Sending datagram message...OK\n");
#ifdef __MINGW32__
       closesocket(sd);
       WSACleanup();
#endif
       return 0;
}

===============================================================
with cygwin environment i can't run multiple listerers... bind error:
Address already in use!
(
building with cygwin:
gcc -o listener.cygwin.exe listener.c
gcc -o send.cygwin.exe send.c
)
but with mingw all works as expected!
(
building with mingw:
gcc -o listener.mingw.exe listener.c -lws2_32
gcc -o send.mingw.exe send.c -lws2_32
or in mingw environment:
gcc -mno-cygwin -o listener.mingw.exe listener.c -lws2_32
gcc -mno-cygwin -o send.mingw.exe send.c -lws2_32
)

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple

Reply via email to