Xiwen Li Xiwen Li - 3 months ago 17
C Question

do udp source port and destination port have to match?

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

EJP EJP
Answer

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().

Comments