Do I have to bind a UDP socket in my client program to receive data? (I always get WSAEINVAL)
With UDP, you have to bind()
the socket in the client because UDP is connectionless, so there is no other way for the stack to know which program to deliver datagrams to for a particular port.
If you could recvfrom()
without bind()
, you'd essentially be asking the stack to give your program all UDP datagrams sent to that computer. Since the stack delivers datagrams to only one program, this would break DNS, Windows' Network Neighborhood, network time sync....
You may have read somewhere on the net that binding in a client is lame, but that advice only applies to TCP connections.
UDP client does not receive data without bind()
Hi Finally I found the answer from EJP answer
It is only necessary to bind() a server, because the clients need a fixed port number to send to. A client needn't bind() at all: an automatic bind() will take place on the first send()/sendto()/recv()/recvfrom() using a system-assigned local port number.
With the help of wireshark I was able to see My PC was sending data from Port 53701 and on first sendto() this port got automatically bind'ed , so had to do a explicit binding.
Is it always required to bind a socket?
No, you don't need to bind().
If you're using a TCP or UDP socket where you are planning to either connect() or send a packet to a destination with sendto(), the kernel will automatically bind the socket to a suitable port number when you try to connect or send. This is generally the preferred way. bind()ing client sockets is considered harmful.
The same is also true of AF_UNIX sockets - the client side does not need to bind, and should not do so normally.
Problem using Connect(), send(), recv, with UDP sockets
You will need to call bind() if you want your program to receive UDP packets. connect() only sets the address that the socket will send packets to if you call send(); it does not associate the socket with a local UDP port to receive on; for that you must call bind().
UDP unable to bind socket
Parenthesis problem.
if( s = socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP) == INVALID_SOCKET)
should be
if((s = socket(PF_INET,SOCK_DGRAM, IPPROTO_UDP)) == INVALID_SOCKET)
In your code 's' is either 0 or 1 after your line.
do udp source port and destination port have to match?
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()
.
Client (python program) does not receive a response back from the server (c program)?
Quick and dirty:
Remove this line from your C code:
claddr.sin_port = htons(PORT_NUM);
Now why:
When you send a message in your python script, your operating system will fill a UDP packet with the destination IP address and port you specified, the IP address of the machine you are using on the source IP field, and finally, a source port assigned "randomly" by the OS. Do notice, this is not the same port as the destination port, and even if it was the case, how would you know what program will receive the source message?(both would be hearing messages from the same port) Luckily, this is not possible.
Now, when your C code receives this packet, it will know who sent the message, and you have access to this information though the sockaddr struct filled by recvfrom. If you want to send some information back, you must send the packet with a destination port(as seen by the server) equal to the source port as seen by the client, which again, is not the same port that you are listening on the server. By doing claddr.sin_port = htons(PORT_NUM)
, you set overwrite the field that contained the source port of the client with the server port, and when you try to send this packet, 2 things may happen:
- If the client ran from the same computer, the destination IP and
source IP will be the same, and you've just set the destination port
to be the port that the server is listening, so you will have a
message loop. - If running on different computers, the packet will be
received by the client computer, but there probably won't be any
programs waiting for messages on that port, so it is discarded.
A half-baked analogy: you receive a letter from a friend, but when writing back to him, you change the number of his house with the number of your house... does not make much sense. Only difference is that this friend of yours moves a lot, and each letter may have a different number, but that is not important.
In theory, you must bind if you want to receive data back, in this case bind is an equivalent to listening to that port. This answer clarifies why it was not necessary in this case: https://stackoverflow.com/a/14243544/6253527
If you are on linux, you can see which port you OS assigned for your UDP socket using sudo ss -antup | grep python
c++ WINSOCK recvfrom no get data from network
Okey, so as ElderBug said
Are you sure you setup the UDP server socket before you send the data ? It's not clear in your question
Yep, it was my fault. The miniseconds decided that sending data on one machine was executed before setting up listener on server. Thank you for answer.
But i dont exactly understand the problem. Shouldn't that data income to receive buffer and wait for "grabbing" it by recvfrom function?
SIP client doesn't accept the response
The problem was in the message header. The part Via has to end with ;rport
, so asterisk does actually report.
Related Topics
Are C++ Libs Created with Different Versions of Visual Studio Compatible with Each Other
What Is the Purpose of Ref-Qualified Member Functions
Why Isn't Rvo Applied to Base Class Subobject Initialization
Why Use Array Size 1 Instead of Pointer
Does Try-Catch Block Decrease Performance
Clang C++ Cross Compiler - Generating Windows Executable from MAC Os X
Calculating and Printing Factorial at Compile Time in C++
How to Use a Custom Type as Key for a Map in C++
Same Class Name in Different C++ Files
How to Pass Multiple Ints into a Vector at Once
Why Doesn't This Reinterpret_Cast Compile
Exact Decimal Datatype for C++
When Is Explicit Move Needed for a Return Statement
Qobject: Cannot Create Children for a Parent That Is in a Different Thread