Yess
Yess

Reputation: 41

How to find server on LAN with sockets (UDP) in C++

Hello fellow programmers! I am writing a program in C++ that is supposed to allow for real time data transfer between 2 computers over LAN using windows sockets. Since the data is supposed to be transferred as fast as possible I use UDP (this is a game, therefore only the newest data is relevant). Now, since I tested it on single machine i use the following code to assign server IP to the client

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;

Now, I need it to run within LAN where the exact addresses of server and client may be unknown. How to connect in such a case? Is it enough if I broadcast to 255.255.255.255? Or maybe there is another way of handshaking 2 computers?

Upvotes: 2

Views: 1067

Answers (1)

Yess
Yess

Reputation: 41

Okay, i finished my project, so I will take the opportunity to show a code I used for finding a server. As suggested, it is based on broadcasting on client side and sending a datagram back, providing server's IP to the client, which is used later to provide directed communication later on.

SERVER:

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);
}

CLIENT:

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;
}

Upvotes: 1

Related Questions