Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 1883
  • Last Modified:

winsock sendto() UDP problem

Hello,
I?m writing a UDP server, using Winsock API 1.1 and VC++ 1.52.
I?ve got a problem using sendto() function. In MSDN they say that the function returns the number of bytes sent, that can be less then the buffer?s length passed as a parameter in sendto(). Is the winsock expecting the last part(s) of the buffer in order to send a complete datagram to the destination, or it is sending an incomplete datagram right away using only the bytes processed (I mean the first part of the buffer)?
How can I get the maximum datagram length? Is the WSAData.iMaxUdpDg value appropriate?

thanks,
Cristi
0
ttsro
Asked:
ttsro
  • 7
  • 5
  • 3
  • +1
1 Solution
 
djbusychildCommented:
This is one of the first things you learn when you start doing socket programming. Put a while loop around your sento and write to ensure that all your data is sent out.

There is no buffering in UDP. Packets are sent out immediately.
0
 
ambienceCommented:
iMAxUdpDg is the upper bound that a udp datagram can have , its far better to use getsockopt() with SO_RCVBUF and SO_SNDBUF to find the size of the buffers assiciated with a socket , you can also change the size if desired.

Whatever you read in MSDN applies only to connection oriented sockets and not UDP , in UDP data is sent atomically , either the whole datagram is sent or nothing is sent at all , you must take care that the data you send is within the buffer limits otherwise what you set is WSAEMSGSIZE and nothing gets transmitted.

If you have larger datagram sizes , you have to incorporate some kind of policy to break them down into smaller pieces with some kind of synchronization information within each datagram , in short words its upto you ...
0
 
makerpCommented:
no

getsockopt with SO_MAX_MSG_SIZE option to get the max size for a datagram. if you are traversing various networks then use 512 bytes as this is the lowest common denominator. if sendto returns less than what you sent you will need to try to resed the whole message or build an application protocol that has sequence numbers etc so your receiver can rebuild the message. UDP will not put messages back together for you
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
djbusychildCommented:
oh yeah, I think I'm confusing write with sendto in terms of putting a while loop on it.. mah bad...

If you try to send too big a packet it'll fail. you don't want to send big packets via UDP anyway, that'd be pretty risky.

0
 
makerpCommented:
you do the while loop with normal stream send, i.e.

/* send a block of data, this returns when all is sent */
int Stream::sendData(char *buffer,int len)
{
     int sent = 0;
     int res = 0;
     /* make sure all the data goes out */
     while(sent < len)
     {
          res = send(sock,buffer + sent,len - sent,0);
          /* catch any errors */
          if(res == SOCKET_ERROR || res == 0)
          {
               last_error = WSAGetLastError();
               return FAILURE;
          }
          /* increase sent */
          sent += res;
     }
     /* we might as well return the amount sent */
     return sent;
}
0
 
djbusychildCommented:
normal stream = TCP
0
 
makerpCommented:
yes thats right
0
 
makerpCommented:
if you need to use UDP packets to send a packet thats too big to go in one hit then you need to write an application level protocol that breaks each packet up and send the subpackets. each subpacket will need a sequence number so the receiver can re-order the packets and form the original message.

this is not simple. if you have large data to send i would use TCP
0
 
djbusychildCommented:
heh heh... makerp, that was just to clarify it to ttsro. =)

ttsro, as makerp and I said it's risky sending big packets via UDP. TCP is used more than 80% (even 90%) of the traffic on the web. UDP is used for a lot of multimedia network architectures. When I'm doing some game coding I use my own application level protocol which sits on top of UDP. Soley for UDP's simple and fast speed. However, this means that you have to take good care of reliability, segmentation, etc etc ...
0
 
ttsroAuthor Commented:
>>ambience:
>in UDP data is sent atomically, either the whole >datagram is sent or nothing is sent at all
r u positive about this?
I also think this is the way it works.

>>makerp:
>getsockopt with SO_MAX_MSG_SIZE option to get...
This option in not available in winsock 1.1
>sendto returns less than what you sent
Have you ever actaully seen this happening?
0
 
makerpCommented:
>getsockopt with SO_MAX_MSG_SIZE option to get...
This option in not available in winsock 1.1

it is not documented to only work on 1.1, although maybe thats the case. i would just chose the lowest common denominator which is 512. the SO_MAX_MSG_SIZE is provided because different network providers allow different max sizes etc

>sendto returns less than what you sent
Have you ever actaully seen this happening?

i have never sent a packet bigger than 512 and never got that problem
0
 
djbusychildCommented:
ttsro, I have implemented a UDP layer before and if the packet is bigger than the maximum size allowed it will simply not be sent at all.
0
 
makerpCommented:
try calling WSAGetLastError and tell us what the error code is, i have a look up table
0
 
ttsroAuthor Commented:
djbusychild:
I know that. Maybe I haven't made myself clear, and sorry if so. I don't want to send larger datagrams than the maximum size allowed by the winsock. My problem is: in winsock documentation, including MSDN, they say - for sendto() the following:

"Return Values
If no error occurs, sendto returns the total number of bytes sent, which can be less than the number indicated by len. Otherwise, a value of SOCKET_ERROR is returned, and ..."

I don't know if this regards UDP, or TCP only, and is it possible for example to want to send 5 bytes and the sendto() to return 3? In this case an ETX flag should be added to the original telegram and the receiver will discard any telegram that desn't contains the ETX.

makerp:
I'll follow your advice and I'll use 512 as maximum length.

0
 
makerpCommented:
are you receiving them okay regardless of whats returned at the sender, ?
0
 
ambienceCommented:
ttsro , do i have to re-post my comment ??
here it is again

Whatever you read in MSDN applies only to connection oriented sockets and not UDP , in UDP data is sent
atomically , either the whole datagram is sent or nothing is sent at all , you must take care that the
data you send is within the buffer limits otherwise what you set is WSAEMSGSIZE and nothing gets transmitted.

so if using UDP you send 5 bytes sendto wont return 3, and the reciever will be receiving all 5 of them or nothing at all. What you may need is  way to notify the sender that his packet has been received and incase you dont get it you must timeout and send a packet that means that it hasnt received something it was expecting.

From the sender side you should try not discard any packet and hold onto it until you get a confimation of its receipt or a re-send request in which case you have to do it again. Remember its UDP and most of the things you have to take care of...

0
 
ambienceCommented:
>>ambience:
>in UDP data is sent atomically, either the whole >datagram is sent or nothing is sent at all
r u positive about this?
---------
I am positive !! , unless someone proves me wrong.

>>makerp:
>getsockopt with SO_MAX_MSG_SIZE option to get...
This option in not available in winsock 1.1
---------
not available , thats news let me check..

>sendto returns less than what you sent
Have you ever actaully seen this happening?
---------
ttsro , why dont u try it out yurself , send one huge packet say a hundred KB and see what sendto returns , this way you'll know what is the truth..
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

  • 7
  • 5
  • 3
  • +1
Tackle projects and never again get stuck behind a technical roadblock.
Join Now