2
votes

I am trying to learn socket-programming with c/c++. I wrote two small udp senders. One is with bind()ing, another is without bind()ing. I built both programs on a remote IP. At the same time, I built a small udp receiver on my local system. I tried to send udp message from both sender programs to my local receiver. But the receiver can only receive message from the sender with bind()ing. And it has to be bound on the same port number with the destination. Otherwise, even with bind()ing, it still doesn't work. But when I moved the sender program without bind()ing to my local system, and sent message to "127.0.0.1" it worked.

So to me, it seems like sending udp packet locally the src port and dest port can be different numbers. But when sending udp packet from a different IP address, the sending and receiving port have to have matching port number. Is that right?

Here is my udp sender program:

#include <iostream>
#include <cstring>
#include <cerrno>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

using namespace std;

int main(int argc, char *argv[]){
    if(argc!=2){
        cout<<"need arg"<<endl;
        return 1;
    }
    int sfd = socket(AF_INET, SOCK_DGRAM, 0);
    struct sockaddr_in des;
    des.sin_family = AF_INET;
    des.sin_port = 9999;
    des.sin_addr.s_addr = inet_addr("my ip address"); //I used "127.0.0.1" when I tried it locally.

    /* this is all the difference between the sender with and without bind()
    struct sockaddr_in sai;
    sai.sin_family = AF_INET;
    sai.sin_port = 5001;
    sai.sin_addr.s_addr = INADDR_ANY;
    if(bind(sfd, (struct sockaddr *)&sai, sizeof sai)==-1){
        cout<<"bind:"<<strerror(errno)<<endl;
        _exit(1);
    }
    cout<<"binded successfully"<<endl;
    */

    int byt = sendto(sfd, argv[1], strlen(argv[1])+1, 0, (struct sockaddr *)&des, sizeof des);
    cout<<byt<<endl;
    if(byt<0){
        cout<<"sendto"<<strerror(errno)<<endl;
    }

    return 0;
}
1
No, I think you're confused about a few key points. Here is a good tutorial that might help: Programming with UDP sockets. This link discusses further the role of bind: stackoverflow.com/questions/3057029/…paulsm4
Each UDP (and TCP) endpoint is characterized by an (address, port) pair. That corresponds pretty well to (machine, program). A port is a characteristic of one endpoint alone, not of the communication channel overall, so there is no requirement that the same port be used at both ends. Usually, it isn't.John Bollinger

1 Answers

4
votes

So to me, it seems like sending udp packet locally the src port and dest port can be different numbers.

Correct.

But when sending udp packet from a different IP address, the sending and receiving port have to have matching port number. Is that right?

No. It doesn't. What you have to do when replying is to make sure to use the source port of the received datagram, returned via recvfrom(), as the target port of the reply datagram in sendto().