Question

I'm trying to broadcast a current time once in 3 seconds and a current date once in 10 seconds. I'm spawning 3 threads: 1 listener, 1 for broadcasting time and 1 broadcasting date. this application is happening on my laptop.

I have a udp listener on my desktop (the same intranet) with which I check my broadcasts.

when I launch the broadcast application on the laptop, I immediately receive a time and a date on my desktop listener (this is obviously expected). the problem is that I only receive the first 2 broadcasts (a time and a date). subsequent broadcasts are not caught by my desktop listener, and I cannot explain why. my laptop app (which broadcasts) also has a listener and it picks them up just fine.

the desktop listener picks up the first set of broadcasts, which tells me that the broadcast is working, but I cannot understand why the laptop receives all broadcasts and the listener doesn't.

here's the full broadcast app code (it's quite long), any help is greatly appreciated.

#include <iostream>
#include <conio.h>
#include <WinSock2.h>
#include <ctime>
#include <string>
#include <Windows.h>
#include <process.h>
#include <conio.h>

#pragma comment (lib, "ws2_32.lib")
using namespace std;
#define PORT 7777

struct tm *currentTimeAndDate;
char currentDate[16];
char currentTime[16];

SOCKET sock;
char recvBuff[50];
int recvBuffLen = 50;
struct sockaddr_in Recv_addr;
struct sockaddr_in Sender_addr;
int len = sizeof(struct sockaddr_in);

void getDate()
{
    string s;
    char a[100];
    time_t t = time(0); // get time now
    struct tm *now = localtime(&t);
    strftime(currentDate, 80, "%d/%m/%Y", now);
}

void getTime()
{
    string s;
    char a[100];
    time_t t = time(0); // get time now
    struct tm *now = localtime(&t);
    strftime(currentTime, 80, "%H:%M:%S", now);
}

void recvFunct(void *param)
{
    while(1)
    {
        recvfrom(sock, recvBuff, recvBuffLen, 0, (sockaddr *)&Sender_addr, &len);
        cout << "received message: " << recvBuff << endl;
    }
}

void sendFunct1(void *param)
{
    while(1)
    {
        getTime();
        if(sendto(sock, currentTime, strlen(currentTime)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
        {
            perror("borhot send: ");
            _getch();
            closesocket(sock);
        }
        Sleep(3000);
    }
}

void sendFunct2(void *param)
{
    while(1)
    {
        getDate();
        if(sendto(sock, currentDate, strlen(currentDate)+1, 0, (sockaddr *)&Sender_addr, sizeof(Sender_addr)) < 0)
        {
            perror("borhot send: ");
            _getch();
            closesocket(sock);
        }
        Sleep(10000);
    }
}

int main()
{
    WSADATA wsaData;
    WSAStartup(MAKEWORD(2, 2), &wsaData);
    sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
    char broadcast = 'a';

    if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof(broadcast)) < 0)
    {
        perror("broadcast options");
        _getch();
        closesocket(sock);
        return 1;
    }

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

    Sender_addr.sin_family = AF_INET;
    Sender_addr.sin_port = htons(PORT);
    Sender_addr.sin_addr.s_addr = inet_addr("255.255.255.255");

    if(bind(sock, (sockaddr*)&Recv_addr, sizeof(Recv_addr)) < 0)
    {
        perror("bind");
        _getch();
        closesocket(sock);
        return 1;
    }

    _beginthread(recvFunct, 0, NULL);
    _beginthread(sendFunct1, 0, NULL);
    _beginthread(sendFunct2, 0, NULL);

    cout << "spawned threads, press any key to exit.. \n";
    _getch();
    closesocket(sock);
    WSACleanup();
    return 0;
}
Was it helpful?

Solution

Your recvFunct uses Sender_addr to store the sender address. So your target address in the send function is compromised.

Your laptop's network card address is stored in that variable. That's the reason why you just stop sending broadcasts.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top