.NET Framework Bookmark and Share   
 index > .NET Framework Networking and Communication > VB.NET, System.Sockets.Socket, and RAW Data Transfer
 

VB.NET, System.Sockets.Socket, and RAW Data Transfer

So what I'm working on is a TFTP implementation, which means that I send out a simple datapacket to Port 69, it responds with a 'session ID' which is the port to use for communications until the end of this session, and then I have to use that port and only that port for subsequent transmissions.

Of course, UDPClient doesn't provide any access at all to the UDP Header.

So I've gone toward using a System.Sockets.Socket to listen for all incoming data on a local port. At this point, I need to be able to use a second System.Sockets.Socket to send information out. Really specifically, I need to be able to construct (from scratch) the IPv4 Header, the UDP Header, and the TFTP datagram.

So I spent the last 3 days implementing IPv4 and UDP. Only to discover that the absolute ONLY way to get System.Sockets.Socket to accept a System.Net.IPEndPoint is to declare it exactly like this:

Dim MySocket As New System.Sockets.Socket(AddressFamily.InterNetwork,SocketType.Raw,Protocol.IP)

Now, if I use any AddressFamily but InterNetwork (or another basic IP Address Family) I can't use an IP Address as a Bind or Target. If I use any Protocol but IP or IPv6, I can't use an IP Address as a Bind or Target. And if I use any SocketType but Raw, I can't get my hooks into the IP or UDP Headers.

The big problem here is that if I'm going to manually construct a UDP Datagram, I must absolutely be able to manually edit the IP Header... while specifying the IP Protocol automatically affixes an IP Header that may or may not be accurate by the time I add my UDP Header and actual data to it.

If anyone can help me find a way to actually establish a raw data connection where I can construct my own IP Header, UDP Header, and data payload from the ground up and actually send it to an IP Address on the internet, it will be greatly appreciated.

Thanks in advance,

Andrew
It never hurts to try. In a worst case scenario, you get to learn what you did wrong and how to fix it and that is at least as valuable as getting it right the first time.
  • Moved byMartin Xie - MSFTMSFT, ModeratorTuesday, August 11, 2009 10:18 AMMove it to Network Communication forum for better support. (From:Visual Basic General)
  •  
Andrew B. Painter
I don't recognise that description of TFTP, I don't know of a 'session ID'. I don't think you need any of the complexity of raw sockets and manually built packets at all. All you need and 1+N UdpClient instances. One on port 69, and one each for each client that connects. From TCP/IP Illustrated Volume 1 "The server [program] then allocates some other unused ephemeral port on the server's host, which is then used by the server for all further packet exchange[s]."

So something like:

Shared Sub Main
...
Dim svr As New UdpClient(69) ' or with an IPEndPoint(localAddr,69) or similar
While Not quit
   Dim rep As New IPEndPoint(IPAddress.Any, 0)
   Dim pkt() As Byte = svr.Receive(rep)
   dim state As New CliState { FirstPacket = pkt, ClientEndPoint = rep } '' can you do this in VB????
   ThreadPool.QueueUserWorkItem(AddressOf Client_Thread, state)
End While
...
End Sub

Sub Client_Thread(state As Object)
   Dim cliState As CliState = CType(state, CliState)
   Dim reply() as Byte = ParseRequest(cliState.FirstPacket) ...
   Dim newSvr = new UdpClient() ' ephemeral port chosen
   newSvr.Send(reply, cliState.ClientEndPoint)
   ' now continue the send receive
   newSvr.Receive(...)
   newSvr.Send(..., cliState.ClientEndPoint)
   ... ...
End Sub

Class CliState
   Public Property FirstPacket As Byte() ... ...
   Public Property ClientEndPoint As IPEndPoint ... ...
End Class



Of course you can handle the threading in whichever way you want, here I've used a thread-pool thread for each client instance.

http://www.alanjmcf.me.uk/ Please follow-up in the newsgroup. If I help, mark the question answered
Alan J. McFarlane
I don't recognise that description of TFTP, I don't know of a 'session ID'.

TFTP is the Trivial File Transfer Protocol as described by Public RFC 1350. I'm working specifically with Revision 2. 'Session ID' refers to Transfer ID, or TID. I'm not sure how you could recognize TFTP and not recognize a reference to Session ID, but hopefully this clarification will help.

I don't think you need any of the complexity of raw sockets and manually built packets at all. All you need and 1+N UdpClient instances. One on port 69, and one each for each client that connects. From TCP/IP Illustrated Volume 1 "The server [program] then allocates some other unused ephemeral port on the server's host, which is then used by the server for all further packet exchange[s]."

TCP specifications are not relevant here, as TFTP relies explicitly and strictly on UDP which relies explicitly and strictly in IPvX (X could be 4 or 6).

A TFTP TID is composed of the Server Port and Client Port as reported directly by the UDP Header.

On the Client Side, UDP SourcePort = Server Port and UDP Destination Port = Client Port.
On the Server Side, UDP SourcePort = Client Port and UDP Destination Port = Server Port.

The Source and Destination IP Addresses as reported by the IP Header are not referenced in the TFTP Specification itself, however real-world testing has proven conclusively that it is extraordinarily meaningful vis a vis hardware and software firewalls (and also that some TFTP Implementations expand the TID to include IP Addresses as well as Ports).

So for example:

Using a System.Net.Sockets.UDPClient, I can receive a WRQ or RRQ Packet on Port 69, and I can retrieve the RemoteIPEndPoint and begin a Session that way, however if I bind the Client to System.Net.IPAddress.Any on the Local side there is NO way at all for me to determine WHAT local IP Address it was received on. In any system with multiple network Adapters (or even multiple IP Addresses) this makes the IP and UDP Header data critical to any meaningful response.

I'm in exactly the same boat with System.Net.Sockets.Socket when it's instantiated with the Dgram Type and UDP Protocol.

So using the RAW Type and the UDP Protocol, I can extract the meaningful information from the IP and UDP Headers. What I can't do at that point is Bind the listening socket to anything but an IP Address, because no matter what Socket is specified it will return ALL UDP Datagrams that come in on ANY Port. I'd pretty obviously rather not process and route all UDP traffic that comes in.

At the same time, if I have the first Socket listening for all the data that's coming in on the appropriate TID Port, I need to be able to use a second Socket to send data out to the remote host or client.

With all of this in mind:

While the first Socket is bound to a local network address and port the second Socket cannot be bound to the same address and port because DotNET throws an exception, and binding the socket is the ONLY way to get the automatically generated IP and UDP Headers set up to send the target system the meaningful TID data. Using my custom IPv4 and UDP Datagrams I can manage to bind the second Socket to the appropriate local IP on any available Port and then send the by-hand UDP Datagram with the meaningful Source/Destination Ports, but I'd rather have the ability to push data onto the network using any available local adapter using my own constructed-by-hand full IPv4+UDP+TFTP Packet structures.

It never hurts to try. In a worst case scenario, you'll learn from it.
Andrew B. Painter

You can use google to search for other answers

Custom Search

More Threads

• Accessing a Web service whith SSL certificate intalled
• Problem in getting local machine's workgroup name
• Need ideas how to solve/implement (send file from exe to web)
• Help! What's (S(q0x0e045zny2ydr02r5quc45)) doing on my site URL?!!!
• Embedded windows usercontrol in to web application
• Problem with sending mail
• Advantage and disadvantage of WPF
• "Speaking" with windows service
• Why does TransferMode have to be StreamedResponse instead of Streamed for web hosted WCF service?
• Automatic Form Filling and Posting