UDP sendto never fails - c++

My application sends UDP packets to different hosts continuously. When a host is alive, UDP packet reaches to the host and sendto function returns number of bytes sent to it. But when a host gets down (cable unplug or reset), sendto function doesn't send UDP packet but still returns number of bytes in buffer. Instead of sending UDP packets, ARP packets get sent to find the host. Why sendto function doesn't return SOCKET_ERROR? WSAGetLastError function returns 0 also. How can I notice error on sending UDP packets to unreachable host?
P.S. my OS is Winodws 7 x64 and my application is native C++ and 64-bit.

The title of your question - "UDP sendto never fails" - is a pretty good one-line summary of UDP.
That's how UDP works - UDP doesn't care if the destination is reachable.
UDP sendto "succeeds" when the packet leaves your application; it doesn't even need to leave your computer as far as UDP is concerned.
The ARP packages are your computer's attempts to find a way to reach the host, but at that point sendto has already "succeeded".
If you want a reliable protocol, UDP is not what you're looking for.

A UDP sendto() cannot possibly return an error of that nature unless you are sending over a connected UDP socket, in which case you may get an error on a subsequent send.

Related

Connect a UDP socket, but still receive datagrams from other sources

Is it possible to set the default destination of a UDP socket just like connect does, but without loosing the ability to receive datagrams from other sources?
I'm talking about the native OS socket API (BSD-socket / winsock2) and I'm interested in answers for both linux and windows platforms.
[EDIT:]
In case this is unclear, here is the problematic part from the connect docs:
If the socket sockfd is of type SOCK_DGRAM then addr is the address to which datagrams are sent by default, and the only address from which datagrams are received.
Is it possible to set the default destination of a UDP socket just
like connect does, but without loosing the ability to receive packages from other sources?
As far as I can tell, it is not -- connect() on a UDP socket both sets a default-send-destination and installs a filter so that incoming UDP packets from all other destinations than the specified address/port are dropped.
My solution to the problem was to just call sendto() and recvfrom() instead (if you have a UDPSocket class or similar in your codebase, you can cache the default-send address as a private member variable in that class, so that the rest of your codebase can just call a Send() method, and leave it to that method to handle the sendto() arguments)

C++ UDP RecvFrom, SendTo Different Sockets

i wrote a multithreaded UDP server after the following scheme:
Scheme:
1 Receiver Thread
(Multiple Worker Threads, each has an own Socket, not bindend ,just created Ipv4, UDP,Datagram)
Message gets pushed to 1 worker which then proceed's it and then sends an answere with its own socket.
Problem:
This works perfectly on all my own test programs but for some odd reason it doesnt work with an old software for what i am emulating the server. The software uses async Wsa (overlapped), but i still doesn't get why it doesnt work.
Confusion:
It works if I use the same socket for sending as i used for receiving the data on the serverside. I dont get why, udp is a connectionless protocol so how can it detect a different socket?
Confusion: It works if I use the same socket for sending as i used for
receiving the data on the serverside. I dont get why, udp is a
connectionless protocol so how can it detect a different socket?
If you look in the UDP headers of the packets you are sending you will notice that they contain a "UDP Source Port" field. That field can be examined by the receiver of the packet (via recvfrom()) to find out which UDP port the sending UDP socket used on the sending machine (note that this is different from the "UDP Destination Port" field that determines which port the packet should be delivered to on the receiving machine). It's possible that in your case, the program you are communicating with is looking at that field and adjusting its behavior based on that field's value.
If you're wondering what that field will be set to if you never called bind() on the sending UDP socket, the answer is that the OS will choose an available UDP port number to send from (essentially an implicit bind()).

How do I respond with a "syn ack" packet when receiving a "syn" packet through a raw socket?

I am curious about raw sockets and and how to create them and would like to implement my own TCP mechanism. I have read some examples and have succeeded with sending both custom made TCP packets and UDP packets with my own written IP header (of course influenced by a lot of examples). I have checked with Wireshark that the packet is reaching its destination, so everything is fine so far.
But regarding TCP packets, to make the full handshake:
Client Server
syn --->
<--- syn ack
ack --->
What do I need from the serverĀ“s point of view to get the syn packet so I can send the syn ack back to the client?
To receive packets on a raw socket, just call recv or recvfrom on it. The OS will return you a copy of the next packet addressed to the machine, with headers and all, which should include address info. Watch the destination address, port, and transport protocol, and ignore any that aren't what you were expecting. (Since the point of a raw socket is that there's no built-in notion of ports or anything the OS could use to route packets to sockets, it doesn't know what program to send it to...so every raw socket should receive every packet addressed to the machine. Meaning you might receive lots of crap you have no interest in.)
Once you see a packet addressed to "you", just build a SYN/ACK packet and send it to the address and port listed as the source in the received packet.
Note, though: the OS will often do its own processing of TCP and UDP packets (including sending ICMP "port unreachable" or other responses for ports it doesn't have listeners for)...and doing your own processing on top of that is bound to cause wackiness. If you're going to implement your own flavor of TCP, you might want to use a different protocol number. (Of course, then most clients won't be able to connect to it...you'd have to make a client as well.)

sending and receiving udp packets on same port

i need my client app to be able to sendto() and recvfrom() through the same port using UDP.
I have discovered i can only bind one socket to the port and it's better to do it when using recvfrom(), otherwise things mess up.
I want to be able to still send UDP packets through that port but binding it to a different socket is a problem as i mentioned above.
What can i do ?
thanks.
This should work fine. One socket bound to a port where you use recvfrom() and sendto() on the same socket. See this example from MSDN that shows recvfrom() in isolation - right around the recvfrom() you should be able to sendto() using that same socket.

Problem using Connect(), send(), recv, with UDP sockets

For my Uni assignment I have to create a fast action paced networked game and so have chosen to use UDP as opposed to TCP. I am aware of a lot of the differences in programming both UDP and TCP and have read through most of the relevant parts of MSDN's documentation on winsock. On MSDN it states that creating a UDP socket via the connect() function should bind the socket to the address and port specified and as a result be able use the send() and recv() functions with the created socket.
For my application I create a client and use connect() using the loopback address which sends a number of packets via the send() function. The client, after calling select(), then receives the packets it sent out. However the result I get from the recv() function is SOCKET_ERROR and the error description using WSAGetLastError() is "An existing connection was forcibly closed by the remote host".
If i use the bind() function and use sendto() to send data over the loopback address, I recv() packets without any errors... Does anyone know why the connect() function is not doing what it is supposed to do, and has anyone been able to use UDP sockets with the connect() function?
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().
"UNIX Network Programming" points out that a connect call made on a UDP client side socket figures out and stores all the state about the destination socket address in advance (masking, selecting interface, etc.), saving the cost of doing so on every ::sendto call. This book claims that ::send vs ::sendto can be up to 3x faster because of this reduced overhead - data can go straight to the NIC driver bypassing most IP stack processing. High performance game programmer's may want to consider this.
you should check Beej's Guide to Network Programming Using Internet Sockets, there are nice examples that address your question.
Keep in mind that the UDP protocol is a "connectionless" protocol meaning that you never ever connect to the host, you just send out data. So you can see that connect as an action is meaningless for UDP.
For UDP you should use sendto() and recvfrom() in these function you specify the address and the buffers and that's about it, everything else that is comfortably handled for you in TCP is gone you have to handle things on your own.
In the MSDN documentation its mentioned that you can in fact somehow use the normal send/recv functions with UDP but why would you when you have separate functions already? Like other commented already connect() for UDP does something else it's not essentially a "connect" operation but a sort of a filter to set up send()/recv() for UDP usage.