1
votes

I am trying to make a c++ program work which is written by somebody else. I am having hard time understanding it. I am not even %100 sure that we can use poll() with a UDP socket but the code I am refactoring, is using poll() to read from udp socket as follows:

fd.fd = m_bsocket;
fd.events = POLLIN;


iPollResult = poll(&fd, 1, iTimeout);

if(iPollResult > 0)
{
    int iReceivedByteCount = recv(m_bsocket, p_pBuffer, p_iBufferSize, 0);
    if(iReceivedByteCount > 0)
    {
        *p_pReadSize = iReceivedByteCount;
    }
    else
    {
        eReturnValue = UDP_READ_ERROR;
    }
}

return eReturnValue;

I tried sending udp packets to this program using command line:

echo "123" | nc -u 127.0.0.1 25

It looks like poll() always times out and returns 0, therefore I can not read anything.

I also wrote a small c# program that sends udp datagram, but I can not receive the message. I am wondering what I am doing wrong...

2
sorry for not including, 1000 ms. I also tried making it 10000 ms, it didn't help. maybe I am creating socket in a wrong way. - erin c
If this is unix, see if netstat and tcpdump can give more information. Similar tools exist for windows. - stefaanv
when I run netstat -lu , I don't see anything that listens on my port 25, is it because I am using poll() or is something else likely to be screwed? - erin c
Is the socket a connected (i.e. created using accept or connect) or unconnected? Although it shouldn't matter, as a UDP socket should be "pollable" no matter if it's connected or unconnected. - Some programmer dude
you don't need to connect() (UDP is connectionless) you need to bind() the socket to the IP of the interface you are listening on or 0.0.0.0 for all interfaces. And when sending to a destination, use sendto() - huysentruitw

2 Answers

2
votes

While UDP sockets can be used to connect to another host, they are mostly used "connectionless". Reading your question and comments it makes no sense that you have a connected socket. Instead it should be connectionless as suggested by WouterH in his comment.

int sockfd = socket(AF_INET, SOCK_DGRAM, 0);

struct sockaddr_in sin = { 0 };
sin.sin_family = AF_INET;
sin.sin_port = htons(25);
sin.sin_addr.s_addr = INADDR_ANY;
bind(sockfd, (struct sockaddr *) &sin, sizeof(sin));

// Make socket non-blocking if needed

With the above code, whenever someone sends UDP packets to port 25 on any address of your host, your socket will intercept it. Use e.g. poll or select to know when data is available.

2
votes

You don't need to call connect() as UDP is connectionless. You need to bind() the socket to the IP of the interface you are listening on or 0.0.0.0 (INADDR_ANY) for all interfaces. And when sending to a destination, use sendto().

For completeness: if you call connect() on a UDP socket, you are just setting a default destination for the send() function (then you can use send instead of sendto).

If you want to receive data, you always have to bind() the socket to the interface, or all interfaces. Beware that you will have to verify the source address from the messages you are receiving. So you might want to filter the sender by using recvfrom() and checking the source address.