Do I Have to Bind a Udp Socket in My Client Program to Receive Data? (I Always Get Wsaeinval)

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



Leave a reply



Submit