2
votes

I have UDP Server program which receives data from port 7888. The server code is below.

//UDPIPV4Server.h
#pragma once

#include <iostream>
#include <string>
#include <winsock2.h>
#include <windows.h>
#include <Ws2tcpip.h>

using std::string;
using std::cout;
using std::endl;
using std::cerr;

class UDPIPV4Server
{
public:
    UDPIPV4Server();
    ~UDPIPV4Server(void);
    UINT type;
    string mac_address;
    UINT port;
    int socket_var;
    struct sockaddr_in si_server, si_client;


    int Config(void);
    int RecvData(char* recv_buffer, int buf_size,string *ip_addr);
};

//UDPIPV4Server.cpp
int UDPIPV4Server::Config(void) {
    WSADATA wsadata;
    int error = WSAStartup(0X0202, &wsadata);

    if(error) {
        cerr<<"UdpIPV4Server.cpp:- WSAStartup failed"<<endl;
        return -1;
    }
    if ((socket_var = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1) {
        cerr<<"UdpIPV4Server.cpp:- socket function failed"<<endl;
        return -1;
    }
    memset((char *) &si_server, 0, sizeof(si_server));
    si_server.sin_family = AF_INET;
    si_server.sin_port = htons(7888);
    char host[NI_MAXHOST] = "10.8.0.2";
    if(inet_pton(AF_INET, host, &si_server.sin_addr) != 1) {
        cerr<<"UdpIPV4Server.cpp: inet_pton() failed\n";
        return -1;
    }
    if(bind(socket_var,(struct sockaddr *)&si_server,sizeof(si_server)) == -1) {
            cerr<<"UdpIPV4Server.cpp:- bind failed: "<<endl;
            return -1;
    }
    return 0;
}

//recv data from the UDP client
//recv_buffer - [out] receive buffer
//buf_size - [in] size of receive buffer in bytes
//ip_addr - [out] ip address of the remote client
int UDPIPV4Server::RecvData(char* recv_buffer, int buf_size, string *ip_addr) {
    int recv_len;
    cout<<"waiting for data\n";
    memset((char*)&si_client, 0, sizeof(struct sockaddr_in));
    int si_client_len = sizeof(si_client);
    if((recv_len = recvfrom(socket_var, recv_buffer, buf_size, 0, (struct sockaddr *)&si_client, &si_client_len)) == -1) {
        cerr<<"udpipv4server.cpp:- recvfrom failed"<<endl;
        return recv_len;
    }
    char client_addr[INET_ADDRSTRLEN];
    cout<<"Received packets from "<<inet_ntoa(si_client.sin_addr)<<":"<<ntohs(si_client.sin_port)<<endl;
    *ip_addr = inet_ntoa(si_client.sin_addr);
    return recv_len;
}
//main.cpp
#include "UDPIPV4Server.h"
int main() {
UDPIPV4Server udp_server;
udp_server.Config();
char recv_frame_buffer[65534] = "";
memset(recv_frame_buffer,0,sizeof(recv_frame_buffer));
int retval;
string ip_addr;
if((retval = udp_server.RecvData(recv_frame_buffer,sizeof(recv_frame_buffer),&ip_addr)) ==  -1) {
    cerr<<"ReceiverCommModule:- Error in receving data"<<endl;
    continue;
}
}

The above program receives data on 10.8.0.2:7888. But this code is not working when data is received. I have checked with wireshark, the data is being received at 10.8.0.2:7888. But socket is unable to read the data from the port.The UDPIPV4Server.config() function passed successfully. But the UDPIPV4Server.RecvData() is not returning. The UDP recvfrom is waiting as such there is no data received. Is it anything wrong with the code? Thank you.

1
If you're writing OS-specific code, it's good to include the related tag (Windows). If UDPIPV4Server is part of a 3rd party library you should name it and provide a link; if it's all your code you should extract/include enough of the library to create a minimal example program that reproduces the problem. "But socket is unable to read the data from the port." - that's too vague: is recvfrom not returning, or returning such that "recvfrom failed" gets printed? - Tony Delroy
"socket is unable to read the data" is not a problem description. Try again. NB Don't print "bind failed", "recvfrom failed", etc. Print the actual error, as errno, or with strerror(), or perror(). Same for all system calls, not just bind(). Otherwise debugging is just a guessing game. - user207421
@TonyD i have edited the code. The issues is UDP recvfrom wait as if no data is received. But in wireshark i can clearly see data being received. - Kumar
I haven't noticed any obvious bug. You could change from inet_pton to .sin_addr.s_addr = htonl(INADDR_ANY); temporarily - which means it will be monitoring all intefaces - see if that's relevant. - Tony Delroy
Make sure your firewall will allow packets on that port - wireshark usually monitors before the firewall. - kbickar

1 Answers

3
votes

I had the same issue. in UDP, recvfrom behaves as if no data were available dispite wireshark confirmed that a valid UDP packet arrived on the correct port. It happens on my compagny's computer but it works fine on my personnal one. I guess this is linked to windows fire wall or antivir that filters incoming packets if the associated port is not allowed for your software. I noticed that recvfrom works once, just after having sent packet through the same port. May be this is linked to my computer's config.