Wiz5100 and UDP

Can anyone point me to some simple doco about how to correctly use UDP with Wiz5100 ?

On devices with the full net support (Cobra+) you can do the following (in pseudocode):

Create IPendpoint EP
Define Socket S
S.Bind to EP
S.Connect to EP
S.Send() request
S.Recieve() response.

In the Wiz you have to use SendTo and RecieveFrom -> I’ve got no idea what the expected way to use these are.

In my case I’m trying to use NTP. So I assume I need to send it a request using 0x1B as the protocol version and expect to get the NTP data back a ~40 byte response that can then be parsed. But I don’t understand the way to use EP’s in this case, since RecvFrom needs a REF to an EP. I’m a little bit lost!


IPEndPoint remoteEp; // don't need to intialize
int rxLength socket.ReceiveFrom(buffer, ref remoteEp);

ref is used so the ReceiveFrom method can create an IPEndPoint and place a reference to it in your variable.

I think you need to use RecieveFrom and SendTo with UDP even on coba

Hi Gus, no definetely Send and Recieve work on a Cobra. The Microsoft libraries handle UDP in this way (we had the conversation when the Wiz5100 code was first introduced in the beta, waaaaay back that making the wiz code the same wasn’t necessary if there was a way around it)

Thanks for the input Mike, so does that mean:

Create IPendpoint EP (to time server address)
Define Socket S
S.Bind to EP
S.Connect to EP
S.SendTo(EP) request
create new IPEP
S.RecieveFrom(IPEP) response.

?

RecieveFrom requires an EndPoint not an IPEndPoint, and VS complains about using an unassigned local variable if you don’t initialise it. Am yet to try it on hardware but I’ve now got:

IPEndPoint ep = new IPEndPoint(Dns.GetHostEntry(TimeServer).AddressList[0], 123);
EndPoint retEP=null;

// Connect to timeserver
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.Bind(ep);
s.Connect(ep);

// Make send/receive buffer
byte[] ntpData = new byte[48];
Array.Clear(ntpData, 0, 48);

// Set protocol version
ntpData[0] = 0x1B;

// Send Request
s.SendTo(ntpData, ep);

// Receive Time
s.ReceiveFrom(ntpData,ref retEP);

Does that look like it makes sense?

Joe, are you out there? Throw me a lifeline ! :slight_smile:

The end point you bind to when you create the socket is the local end point (aka the IP address of the device you are using, not the server you want to connect to). You can create the local IPEndPoint with IPAddress.Any and the underlying framework “should” use the appropriate IP address, although I don’t like to leave this up to random magic in my code and typically put the IP address there myself.

You don’t need to call Connect if you are using the SendTo and ReceiveFrom methods. (Microsoft says it like it’s OK to do it anyway, but in reality you should not call Connect if using those methods to get and send data).

More information can be had here:

Also, remember that ReceiveFrom is a blocking call, and won’t return until there is some data there. You might want to check for data using the Socket.Available property, or set an appropriate read timeout in your code. Another method would be to make the receive method of your code it’s own separate thread so it doesn’t block the main code. If you use a timeout, when the timeout is reached the ReceiveFrom returns immediately and then throws a SocketException, so remember to catch it.

with W5100 support, with UDP you can not use Send(), Receive(. you need to use ReceiveFrom() and SendTo().

This document has some UDP examples with Wiznet
[url]http://www.tinyclr.com/downloads/Shield/Broch_EthernatShield.pdf[/url]

Please let me know if I missed some points that I did not answer.

OK the mind-issue here is still the transition from a piece of code that has a SEND example and a different piece of code with a RECIEVE example; and making this work in a scenario that needs to perform a transaction that has a request and then recieves a response.

So what I think I’m gathering here is:

I need two endpoints - one IPEndPoint to SendTo(), one EndPoint to RecieveFrom().

Bind the SEND and RECV EP’s to the same port, SEND to the remote IP of the NTP server and RECV to the local IP (or the .Any)

SendTo the remote EP - starts the transaction
Check if there’s data, and then RecvFrom.

I’ll try that out…

Joe, that link has a spelling mistake that irks me something bad - EthernEt not nAt. Worth fixing :slight_smile:

An important note for you:
EndPoint in RecieveFrom()is a returned value.
It contains the remote IP address and remote UDP port associated with the received message. So you need to check it to ensure that the message is coming from the correct IP address (the NTP server in your case).

The whole document will be changed soon :wink: