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)的LAN服务器+;_C++_Sockets_Udp_Connection - Fatal编程技术网

C++ 如何在C+中查找带有套接字(UDP)的LAN服务器+;

C++ 如何在C+中查找带有套接字(UDP)的LAN服务器+;,c++,sockets,udp,connection,C++,Sockets,Udp,Connection,各位程序员好!我正在编写一个C++程序,它允许使用Windows套接字在局域网上的2台计算机之间进行实时数据传输。由于数据应该尽可能快地传输,我使用UDP(这是一个游戏,因此只有最新的数据是相关的)。现在,因为我在一台机器上测试了它,所以我使用以下代码将服务器IP分配给客户机 SOCKADDR_IN server_address; server_address.sin_family = AF_INET; server_address.sin_port = htons(PORT); server_

各位程序员好!我正在编写一个C++程序,它允许使用Windows套接字在局域网上的2台计算机之间进行实时数据传输。由于数据应该尽可能快地传输,我使用UDP(这是一个游戏,因此只有最新的数据是相关的)。现在,因为我在一台机器上测试了它,所以我使用以下代码将服务器IP分配给客户机

SOCKADDR_IN server_address;
server_address.sin_family = AF_INET;
server_address.sin_port = htons(PORT);
server_address.sin_addr.S_un.S_un_b.s_b1 = 127;
server_address.sin_addr.S_un.S_un_b.s_b2 = 0;
server_address.sin_addr.S_un.S_un_b.s_b3 = 0;
server_address.sin_addr.S_un.S_un_b.s_b4 = 1;

现在,我需要它在局域网内运行,在局域网内,服务器和客户端的确切地址可能未知。在这种情况下如何连接?广播到255.255.255.255够了吗?或者可能有另一种方式与两台计算机握手?

好的,我完成了我的项目,所以我将借此机会展示我用于查找服务器的代码。正如所建议的,它基于客户端广播并发送数据报,向客户端提供服务器的IP,稍后用于提供定向通信

服务器:

bool handshakeS()
{
    SOCKET sockhs;
    sockhs = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    char broadcast = '1';
    if (setsockopt(sockhs, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
    {
        closesocket(sockhs);
        return false;
    }

    struct sockaddr_in Recv_addr;
    struct sockaddr_in Sender_addr;

    int len = sizeof(struct sockaddr_in);

    char recvbuff[1];
    int recvbufflen = 1;
    char sendMSG[] = "";

    Recv_addr.sin_family = AF_INET;
    Recv_addr.sin_port = htons(PORTHS);
    Recv_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockhs, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
    {
        closesocket(sockhs);
        return false;
    }
    recvfrom(sockhs, recvbuff, recvbufflen, 0, (sockaddr*)&Sender_addr, &len);

    if (sendto(sockhs, sendMSG, strlen(sendMSG) + 1, 0, (sockaddr*)&Sender_addr, sizeof(Sender_addr)) < 0)
    {
        closesocket(sockhs);
        return false;
    }
    return true;
    closesocket(sockhs);
}
bool握手()
{
插座;
sockhs=插座(AF_INET、SOCK_DGRAM、IPPROTO_UDP);
字符广播='1';
if(setsockopt(sockhs、SOL_SOCKET、SO_BROADCAST和BROADCAST、sizeof(BROADCAST))<0)
{
闭合插座(插座);
返回false;
}
Recv_addr中的结构sockaddr_;
发送方地址中的结构sockaddr\u;
int len=sizeof(结构sockaddr_in);
char recvbuff[1];
int recvbufflen=1;
char sendMSG[]=“”;
Recv_addr.sin_family=AF_INET;
Recv_addr.sin_port=htons(端口号);
Recv_addr.sin_addr.s_addr=INADDR\u ANY;
如果(绑定(sockhs,(sockaddr*)和Recv_addr,sizeof(Recv_addr))<0)
{
闭合插座(插座);
返回false;
}
recvfrom(Socks、recvbuff、recvbufflen、0、(sockaddr*)和发送方地址和len);
如果(发送到(sockhs,sendMSG,strlen(sendMSG)+1,0,(sockaddr*)和发送方地址,sizeof(发送方地址))<0
{
闭合插座(插座);
返回false;
}
返回true;
闭合插座(插座);
}
客户:

bool handshakeC(int& ip1temp, int& ip2temp, int& ip3temp, int& ip4temp)
{
    SOCKET sockhs;
    sockhs = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    char broadcast = '1';
    if (setsockopt(sockhs, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
    {
        closesocket(sockhs);
        return false;
    }

    struct sockaddr_in Recv_addr;
    struct sockaddr_in Sender_addr;

    int len = sizeof(struct sockaddr_in);

    char sendMSG[] = ""; //may be used for authorization
    char recvbuff[1] = "";
    int recvbufflen = 1;

    Recv_addr.sin_family = AF_INET;
    Recv_addr.sin_port = htons(PORTHS);
    Recv_addr.sin_addr.s_addr = INADDR_BROADCAST;

    sendto(sockhs, sendMSG, strlen(sendMSG) + 1, 0, (sockaddr*)&Recv_addr, sizeof(Recv_addr));
    recvfrom(sockhs, recvbuff, recvbufflen, 0, (sockaddr*)&Recv_addr, &len);

    ip1temp = Recv_addr.sin_addr.S_un.S_un_b.s_b1;
    ip2temp = Recv_addr.sin_addr.S_un.S_un_b.s_b2;
    ip3temp = Recv_addr.sin_addr.S_un.S_un_b.s_b3;
    ip4temp = Recv_addr.sin_addr.S_un.S_un_b.s_b4;
    closesocket(sockhs);
    return true;
}
bool握手(int&ip1temp、int&ip2temp、int&ip3temp、int&ip4temp)
{
插座;
sockhs=插座(AF_INET、SOCK_DGRAM、IPPROTO_UDP);
字符广播='1';
if(setsockopt(sockhs、SOL_SOCKET、SO_BROADCAST和BROADCAST、sizeof(BROADCAST))<0)
{
闭合插座(插座);
返回false;
}
Recv_addr中的结构sockaddr_;
发送方地址中的结构sockaddr\u;
int len=sizeof(结构sockaddr_in);
char sendMSG[]=“”;//可用于授权
char recvbuff[1]=“”;
int recvbufflen=1;
Recv_addr.sin_family=AF_INET;
Recv_addr.sin_port=htons(端口号);
Recv_addr.sin_addr.s_addr=INADDR_广播;
发送到(sockhs,sendMSG,strlen(sendMSG)+1,0,(sockaddr*)和Recv_addr,sizeof(Recv_addr));
recvfrom(sockhs、recvbuff、recvbufflen、0、(sockaddr*)和Recv_addr和len);
ip1temp=Recv_addr.sin_addr.S_un.S_un_b.S_b1;
ip2temp=Recv_addr.sin_addr.S_un.S_un_b.S_b2;
ip3temp=Recv_addr.sin_addr.S_un.S_un_b.S_b3;
ip4temp=Recv_addr.sin_addr.S_un.S_un_b.S_b4;
闭合插座(插座);
返回true;
}

好的,我已经完成了我的项目,所以我将借此机会展示我用于查找服务器的代码。正如所建议的,它基于客户端广播并发送数据报,向客户端提供服务器的IP,稍后用于提供定向通信

服务器:

bool handshakeS()
{
    SOCKET sockhs;
    sockhs = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    char broadcast = '1';
    if (setsockopt(sockhs, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
    {
        closesocket(sockhs);
        return false;
    }

    struct sockaddr_in Recv_addr;
    struct sockaddr_in Sender_addr;

    int len = sizeof(struct sockaddr_in);

    char recvbuff[1];
    int recvbufflen = 1;
    char sendMSG[] = "";

    Recv_addr.sin_family = AF_INET;
    Recv_addr.sin_port = htons(PORTHS);
    Recv_addr.sin_addr.s_addr = INADDR_ANY;

    if (bind(sockhs, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
    {
        closesocket(sockhs);
        return false;
    }
    recvfrom(sockhs, recvbuff, recvbufflen, 0, (sockaddr*)&Sender_addr, &len);

    if (sendto(sockhs, sendMSG, strlen(sendMSG) + 1, 0, (sockaddr*)&Sender_addr, sizeof(Sender_addr)) < 0)
    {
        closesocket(sockhs);
        return false;
    }
    return true;
    closesocket(sockhs);
}
bool握手()
{
插座;
sockhs=插座(AF_INET、SOCK_DGRAM、IPPROTO_UDP);
字符广播='1';
if(setsockopt(sockhs、SOL_SOCKET、SO_BROADCAST和BROADCAST、sizeof(BROADCAST))<0)
{
闭合插座(插座);
返回false;
}
Recv_addr中的结构sockaddr_;
发送方地址中的结构sockaddr\u;
int len=sizeof(结构sockaddr_in);
char recvbuff[1];
int recvbufflen=1;
char sendMSG[]=“”;
Recv_addr.sin_family=AF_INET;
Recv_addr.sin_port=htons(端口号);
Recv_addr.sin_addr.s_addr=INADDR\u ANY;
如果(绑定(sockhs,(sockaddr*)和Recv_addr,sizeof(Recv_addr))<0)
{
闭合插座(插座);
返回false;
}
recvfrom(Socks、recvbuff、recvbufflen、0、(sockaddr*)和发送方地址和len);
如果(发送到(sockhs,sendMSG,strlen(sendMSG)+1,0,(sockaddr*)和发送方地址,sizeof(发送方地址))<0
{
闭合插座(插座);
返回false;
}
返回true;
闭合插座(插座);
}
客户:

bool handshakeC(int& ip1temp, int& ip2temp, int& ip3temp, int& ip4temp)
{
    SOCKET sockhs;
    sockhs = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);

    char broadcast = '1';
    if (setsockopt(sockhs, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
    {
        closesocket(sockhs);
        return false;
    }

    struct sockaddr_in Recv_addr;
    struct sockaddr_in Sender_addr;

    int len = sizeof(struct sockaddr_in);

    char sendMSG[] = ""; //may be used for authorization
    char recvbuff[1] = "";
    int recvbufflen = 1;

    Recv_addr.sin_family = AF_INET;
    Recv_addr.sin_port = htons(PORTHS);
    Recv_addr.sin_addr.s_addr = INADDR_BROADCAST;

    sendto(sockhs, sendMSG, strlen(sendMSG) + 1, 0, (sockaddr*)&Recv_addr, sizeof(Recv_addr));
    recvfrom(sockhs, recvbuff, recvbufflen, 0, (sockaddr*)&Recv_addr, &len);

    ip1temp = Recv_addr.sin_addr.S_un.S_un_b.s_b1;
    ip2temp = Recv_addr.sin_addr.S_un.S_un_b.s_b2;
    ip3temp = Recv_addr.sin_addr.S_un.S_un_b.s_b3;
    ip4temp = Recv_addr.sin_addr.S_un.S_un_b.s_b4;
    closesocket(sockhs);
    return true;
}
bool握手(int&ip1temp、int&ip2temp、int&ip3temp、int&ip4temp)
{
插座;
sockhs=插座(AF_INET、SOCK_DGRAM、IPPROTO_UDP);
字符广播='1';
if(setsockopt(sockhs、SOL_SOCKET、SO_BROADCAST和BROADCAST、sizeof(BROADCAST))<0)
{
闭合插座(插座);
返回false;
}
Recv_addr中的结构sockaddr_;
发送方地址中的结构sockaddr\u;
int len=sizeof(结构sockaddr_in);
char sendMSG[]=“”;//可用于授权
char recvbuff[1]=“”;
int recvbufflen=1;
Recv_addr.sin_family=AF_INET;
Recv_addr.sin_port=htons(端口号);
Recv_addr.sin_addr.s_addr=INADDR_广播;
发送到(sockhs,sendMSG,strlen(sendMSG)+1,0,(sockaddr*)和Recv_addr,sizeof(Recv_addr));
recvfrom(sockhs、recvbuff、recvbufflen、0、(sockaddr*)和Recv_addr和len);
ip1temp=Recv_addr.sin_addr.S_un.S_un_b.S_b1;
ip2temp=Recv_addr.sin_addr.S_un.S_un_b.S_b2;
ip3temp=Recv_addr.sin_addr.S_un.S_un_b.S_b3;
ip4temp=Recv_addr.sin_addr.S_un.S_un_b.S_b4;
闭合插座(插座);
返回true;
}

您可以有一个单独的广播阶段,客户端在该阶段向网络发送广播。服务器监视这些消息并用自己的地址进行回复。一个限制是广播不能在具有相同网络掩码的网络段之间传递。为了克服这个问题,您可以在一个固定的、众所周知的地址上安装一个“目录”服务器,客户机可以在该服务器上进行连接,并获得一个k的列表