How do I use C++ to read data from a TCP port/socket/etc.?
To clarify, we have the LabVIEW dashboard VI sending a bunch of TCP data to port 1500. How do I access (with the C++ on the cRIO) the data that is getting sent to this port?
I have seen some stuff about “winsock” and so forth but I am getting absolutely nowhere as to how to implement it. I mean, even the include statement for “winsock2.h” isn’t working … Does anyone have any insight on this matter? I’m fairly well-versed in C++ but I’m completely new to TCP.
TCP and UDP code will be horrible to write in C++, especially since LabView is the officially supported language for the cRIO, because NI makes both of them, and C++/Java just happen to work, especially since I don’t think WPILib has anything built in for TCP or UDP. Try using the serial port, WPILib has a class SerialPort.cpp, you would just have to modify the Labview code to send the data via serial port (to do this you will need a null modem cable, not a normal serial cable). Writing serial code for the robot in C++ is extremely easy, and the data can send really fast (not comparatively of course, but you can set the baud rate higher if needed), I think I was able to write the serial code in 3 hours.
TCP and UDP will be much harder, especially since I am not even sure if the cRIO has the capability to do that through C++.
One problem is that you’re trying to use “winsock”. That is the windows/microsoft flavor of sockets programming. The concepts will be the same on the cRio but the specific function names and #include files will be different.
Just google for UDP socket programming examples - it is pretty straightforward. The network programming API in vxWorks is straight from BSD 4.4 and is very standard stuff. On the DS side, it should work fine with the the LabView UDP infrastructure.
Aligning your data will be more trouble that the actual socket code. For example, is the PowerPC side big or little-endian? The PC is little-endian, the PowerPC might be big endian thus you would have to byte-swap your data (there are functions in LabView to do this).
Check here for one example (http://www.linuxhowtos.org/C_C++/socket.htm). About 2/3rds of the way down a client server model using UDP is shown. This is for Linux but uses the same API as VxWorks. The winsock API (if you use C/C++ on your DS) is a wee bit different setting things up than VxWorks or Linux (one xtra call I think - WSAStartup?) but after that is identical to the examples.
Forgive me, but doesn’t the WPILib have something in it that allows you to craft what it calls “Serial Packets/Blocks” something like that? They let you put a custom payload into a packet and send it to the driver’s station. I could’ve sworn they did.
We used UDP on the 'bot last season for communicating from Arduinos to the cRIO. The one thing that we found is that the WPILib has issues with unread UDP packets. Evidently, the WPILib is always monitoring and hooking UDP traffic (it may do something similar with TCP traffic) so that rather than dropping a packet on the floor as it should, WPILib tries to buffer everything. I can see why they want to do this (in case things start to fall behind, you don’t want important control packets dropped), but it’s against what UDP was built to do. Nonetheless, if you don’t service the UDP packets (say, it’s a periodic transmission from your RPM sensor), they eventually cause the whole robot to lock up when the internal WPILib buffers overflow. This is clearly a bug in WPILib. However, you can get around it by always reading the UDP socket and tossing the packet away in your teleop disabled routine.
We have written a netconsole replacement called netterm. It is written in C++ using winsock to communicate with the cRIO via UDP but the netterm program is written with general purpose in mind so it has options to communicate via either UDP or TCP and can specify different ports. It even supports ANSI escape sequences for color fonts. It is purposefully written in such a way that the TCP/UDP communication is a reusable library module with a server/client pair. The server side is a multi-threaded listener that can handle multiple communication streams. If you are interested in how this work, the NetTerm source code can be found here. http://proj.titanrobotics.net/hg/Frc/Tools/file/411d83bde9d6/NetTerm
The network library can be found here. http://proj.titanrobotics.net/hg/Frc/Tools/file/411d83bde9d6/winlib
WPILib has a built-in mechanism called ‘NetworkTables’ that you can use to transfer data to/from the robot via TCP to external programs, in particular the SmartDashboard. You can access NetworkTables from C++, Java, LabVIEW, and Python.