【问题标题】:Multiple servers with single client具有单个客户端的多个服务器
【发布时间】:2014-09-26 15:41:36
【问题描述】:

场景:多台服务器正在监听,单个客户端将向网络上的所有机器发送 UDP 广播,服务器将回复。 (目标:获取所有服务器的ip地址)

这是客户端代码:

int main()
{
    struct sockaddr_in connectedSocket;
    int length=sizeof(connectedSocket);
    int iResult = 0, iOptVal = 0, nOptiontValue = 1;
    SOCKET Socket;

    char receiveBuffer[1000];
    char message[1000];

    //Clear the buffer by filling null, it might have previously received data
    memset(receiveBuffer,'\0', 1000);

    WSADATA wsa;
    //Initialise winsock
    printf("\nInitialising Winsock...\n");
    if (WSAStartup(MAKEWORD(2,2),&wsa) != 0)
    {
        printf("\nFailed. Error Code : %d",WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    printf("\n.........Initialised.\n");

    //Create socket
    Socket = socket(AF_INET, SOCK_DGRAM, 0);
    if (Socket == SOCKET_ERROR)
    {
        printf("Create a UDP socket failed with error = %d\n" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }

    //Set socket options to broadcast
    iResult = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST,(char *) &iOptVal, sizeof (iOptVal));
    if(iResult == SOCKET_ERROR) 
    {
        printf("Set socket options failed with error = %d\n" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }

    //Setup address structure
    memset((char *) &connectedSocket, 0, sizeof(connectedSocket));
    connectedSocket.sin_family = AF_INET;
    connectedSocket.sin_port = htons(PORT);
    connectedSocket.sin_addr.s_addr = INADDR_BROADCAST;

    while(1)
    {
        printf("\n\n\nEnter message : ");
        gets(message);

      //send the message
        if (sendto(Socket, message,sizeof(message) , 0 , (struct sockaddr *) &connectedSocket, sizeof(connectedSocket)) == SOCKET_ERROR)
        {
            printf("\nsendto() failed with error code : %d" , WSAGetLastError());
            exit(EXIT_FAILURE);
        }

        printf("\nMessage Successfully sent to Server");
        // fflush(stdout);

        if (recvfrom(Socket, receiveBuffer, 1000, 0, (struct sockaddr *) &connectedSocket,&length) == SOCKET_ERROR)
        {
           printf("\nrecvfrom() failed with error code : %d" , WSAGetLastError());
           exit(EXIT_FAILURE);
        }

        printf("\nServer Says : ");
        printf(receiveBuffer,sizeof(receiveBuffer));

    }

    closesocket(Socket);
    WSACleanup();

    return 0;
}

当我运行它时,我得到了

sendto() 失败,错误代码:10013

我查看了winsock错误,它说

试图以访问权限禁止的方式访问套接字。一个例子是在没有使用 setsockopt(SO_BROADCAST) 设置广播权限的情况下将广播地址用于 sendto。

但我将 sockopt 设置为 SO_BROADCAST。谁能告诉我为什么会这样?

【问题讨论】:

    标签: c visual-c++ winsock2


    【解决方案1】:

    您发布的代码的相关部分在这里:

    int iResult = 0, iOptVal = 0, nOptiontValue = 1;
    
    ...
    
    //Set socket options to broadcast
    iResult = setsockopt(Socket, SOL_SOCKET, SO_BROADCAST,(char *) &iOptVal, sizeof (iOptVal));
    if(iResult == SOCKET_ERROR) 
    {
        printf("Set socket options failed with error = %d\n" , WSAGetLastError());
        exit(EXIT_FAILURE);
    }
    

    请注意,变量 iOptVal 已初始化为 0。它没有在其他任何地方修改。然后将该变量传递给setsockopt() 函数。

    这会将SO_BROADCAST 选项设置为FALSE(这是默认值,因此实际上它不会更改该值)。

    设置它是不够的。您必须将其设置为正确的值。应该是TRUE

    您可以通过将变量初始化为1 而不是0 来做到这一点。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多