?
Solved

winsock sendto() UDP problem

Posted on 2001-06-18
17
Medium Priority
?
1,807 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
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
 
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 225 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

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

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…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to user default arguments when defining functions. This method of defining functions will be contrasted with the non-default-argument of defining functions.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

777 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