Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;UDP服务器仅在获取客户端时发送消息';s地址配置_C++_Sockets_Udp - Fatal编程技术网

C++ C++;UDP服务器仅在获取客户端时发送消息';s地址配置

C++ C++;UDP服务器仅在获取客户端时发送消息';s地址配置,c++,sockets,udp,C++,Sockets,Udp,我的目的是创建一个UDP发送器,将消息广播到特定的IP和端口,而无需任何配置要求。我在si_me变量中定义了struct sockaddr_来设置服务器配置并绑定它: si_me.sin_family = AF_INET; si_me.sin_port = htons(PORT); si_me.sin_addr.s_addr = htonl(INADDR_ANY); if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)

我的目的是创建一个UDP发送器,将消息广播到特定的IP和端口,而无需任何配置要求。我在si_me变量中定义了
struct sockaddr_来设置服务器配置并绑定它:

si_me.sin_family = AF_INET;
si_me.sin_port = htons(PORT);
si_me.sin_addr.s_addr = htonl(INADDR_ANY);
if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
    {
        die("bind");
    }
我希望当我在
si_me
变量中将数据发送到配置的IP和端口时,每个客户端都可以接收到消息,但没有发生,在Linux终端上使用UDP客户端和
nc 127.0.0.1 9090-u
命令,我无法接收任何消息! 我发现对于每个客户机,我都应该在si_other
变量中创建一个
struct sockaddr_。客户端应向我发送消息,以便我可以获取客户端的配置:

if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, (socklen_t*)&slen)) == -1)
        {
            die("recvfrom()");
        }
因此,现在使用
si_other
变量,我可以成功地发送消息。我检查了
si_other
变量,发现IP与服务器IP相同,但每个客户端的端口不同,因此,在不知道目标端口的情况下,我无法向客户端发送数据

以下是完整的源代码:

int main(void)
{
    struct sockaddr_in si_me, si_other;

    int s, i, slen = sizeof(si_other) , recv_len;
    char* msg = "Hellooooo\n";
    char buf[BUFLEN] ;

    //create a UDP socket
    if ((s=socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
    {
        die("socket");
    }

    // zero out the structure
    memset((char *) &si_me, 0, sizeof(si_me));

    si_me.sin_family = AF_INET;
    si_me.sin_port = htons(PORT);
    si_me.sin_addr.s_addr = htonl(INADDR_ANY);

    std::cout << si_me.sin_addr.s_addr << std::endl ;
    std::cout << si_me.sin_port << std::endl ;
    std::cout << si_other.sin_addr.s_addr << std::endl ;
    std::cout << si_other.sin_port << std::endl ;
    if( bind(s , (struct sockaddr*)&si_me, sizeof(si_me) ) == -1)
        {
             die("bind");
        }

    // waiting to recieve client's message
    std::cout << "Waiting for start command ... " << std::endl ;
    if ((recv_len = recvfrom(s, buf, BUFLEN, 0, (struct sockaddr *) &si_other, (socklen_t*)&slen)) == -1)
        {
            die("recvfrom()");
        }
    std::cout << si_me.sin_addr.s_addr << std::endl ;
    std::cout << si_me.sin_port << std::endl ;
    std::cout << si_other.sin_addr.s_addr << std::endl ;
    std::cout << si_other.sin_port << std::endl ;
    long count = 0 ;
    while(0)
    {

            if (sendto(s, msg, strlen(msg), 0, (struct sockaddr*) &si_other, slen) == -1)
            {
                die("sendto()");
            }
            std::cout << "Message number " << ++ count << " has been sent" << std::endl ;

    }

    return 0;
}
int main(无效)
{
结构sockaddr_在si_me中,si_other;
int s,i,slen=sizeof(si_other),recv_len;
char*msg=“hellooo\n”;
char-buf[BUFLEN];
//创建UDP套接字
if((s=套接字(AF_INET,SOCK_DGRAM,IPPROTO_UDP))=-1)
{
模具(“插座”);
}
//将结构归零
memset((char*)&si_-me,0,sizeof(si_-me));
si_me.sin_family=AF_INET;
si_me.sin_port=htons(port);
si_me.sin_addr.s_addr=htonl(在任何情况下);
std::cout在完整的源代码中没有
bind()
调用。 调用
recvfrom()之前需要它

因此,将bind()调用添加到服务器的源:

if (bind(s, (struct sockaddr*)&si_me, sizeof(si_me)) == -1)
{
    die("bind");
}

如果要在同一主机中使用客户端和服务器,则应将不同的端口绑定到客户端而不是服务器。

要发送广播消息,必须使用级别
solu SOCKET
和选项名
SO_broadcast
(请参阅
SOCKET(7)
手册页)调用
setsockopt
.因此,在创建套接字之后,(在客户端),您应该有如下代码:

int turn_on = 1;
retval = setsockopt(s, SOL_SOCKET, SO_BROADCAST, &turn_on, (socklen_t)sizeof(turn_on));
然后,发送方可以在其发送中指定广播地址,广播域内的任何电台都应该能够接收该地址。任何服务器都需要绑定到广播地址本身,或者绑定到
INADDR\u any
,才能接收此类广播

这通常的工作方式是:

  • 服务器创建套接字,并使用
    INADDR\u ANY
  • 客户端创建套接字,不绑定它,但添加
    SO\u广播
    选项
  • 客户端使用缓冲区调用
    sendto
    ,并在
中指定广播地址和已知端口
  • 服务器调用
    recvfrom
    ,并在返回值中接收数据报有效负载和客户端地址
  • 服务器使用上面获得的客户机地址调用
    sendto
    (因此客户机使用的端口无关紧要——服务器将知道客户机的端口和IP地址)
  • 客户端在同一套接字上调用
    recvfrom
    ,以接收来自服务器的回复消息
  • 通常有两个可用的广播地址:一个特定于子网(由
    ifconfig
    显示)——类似于192.168.1.255——和全局广播地址——255.255.255.255


    监听任何一个
    都应允许您接收发送到广播地址(或属于服务器机器的单播地址)的数据报。

    使用当前子网的广播地址: