Solved

winsock sendto() UDP problem

Posted on 2001-06-18
17
1,719 Views
Last Modified: 2010-08-05
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
Comment
Question by:ttsro
  • 7
  • 5
  • 3
  • +1
17 Comments
 
LVL 5

Expert Comment

by:djbusychild
ID: 6204796
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
 
LVL 22

Expert Comment

by:ambience
ID: 6204945
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
 
LVL 10

Expert Comment

by:makerp
ID: 6205674
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
 
LVL 5

Expert Comment

by:djbusychild
ID: 6207214
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
 
LVL 10

Expert Comment

by:makerp
ID: 6207231
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
 
LVL 5

Expert Comment

by:djbusychild
ID: 6207330
normal stream = TCP
0
 
LVL 10

Expert Comment

by:makerp
ID: 6207433
yes thats right
0
 
LVL 10

Expert Comment

by:makerp
ID: 6207442
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
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 5

Expert Comment

by:djbusychild
ID: 6207505
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
 

Author Comment

by:ttsro
ID: 6209383
>>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
 
LVL 10

Expert Comment

by:makerp
ID: 6209472
>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
 
LVL 5

Expert Comment

by:djbusychild
ID: 6211415
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
 
LVL 10

Expert Comment

by:makerp
ID: 6211607
try calling WSAGetLastError and tell us what the error code is, i have a look up table
0
 

Author Comment

by:ttsro
ID: 6211764
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
 
LVL 10

Expert Comment

by:makerp
ID: 6212028
are you receiving them okay regardless of whats returned at the sender, ?
0
 
LVL 22

Accepted Solution

by:
ambience earned 75 total points
ID: 6212857
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
 
LVL 22

Expert Comment

by:ambience
ID: 6212862
>>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

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
Templates For Beginners Or How To Encourage The Compiler To Work For You Introduction This tutorial is targeted at the reader who is, perhaps, familiar with the basics of C++ but would prefer a little slower introduction to the more ad…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now