After the previous blog post Communications between two MatLabs (1) over file, Aaron Piccirilli in our lab suggested a more efficient way to communicate between two matlabs, i.e. over socket. Below is the source code provided by Aaron:
udpSocket = udp('127.0.0.1', 'LocalPort', 2121, 'RemotePort', 2122); fopen(udpSocket); udpCleaner = onCleanup(@() fclose(udpSocket)); for ii = 1:100 fprintf(udpSocket, '%d%f', [ii ii/100]); disp(['Sending ' num2str(ii)]); pause(0.1); end
udpSocket = udp('127.0.0.1', 'LocalPort', 2122, 'RemotePort', 2121); fopen(udpSocket); udpCleaner = onCleanup(@() fclose(udpSocket)); while(1) if udpSocket.BytesAvailable ii = fscanf(udpSocket, '%d%f'); disp(['Received' num2str(ii(1)) '-' num2str(ii(2))]) end end
More words from Aaron:
I also wrote a couple of quick tests to compare timing by having each method pass 10,000 random integers as quickly as they could. Using UDP is over four times faster on my work machine, and would be sufficient to keep up with sampling rates up to about 900 Hz, whereas the file-based transfer became too slow at about 200 Hz.
Obviously these rates and timings are going to be system and data-dependent, but the UDP implementation is about the same amount of code. It has some added benefits, too. First is what I mentioned before – that this allows you to communicate between different languages. Second, though, is what might be more important: buffer management. If your data source is sending data faster than you can process it, even for just a moment, the UDP method handles that gracefully with a buffer. To get the same functionality with the file method you have to write your own buffer maintenance – not too tricky, but adds another layer of complexity and probably won’t be as efficient.
I did a similar timing test passing 40 floats each time (say for 20 channels of NIRS data) instead of a single integer and the timing did not really change on my machine.
I also tested the above scripts, and they work beautifully! I definitely recommend this method over the ‘file’ method. One thing to note: when you Ctrl-C to quit the program, remember to close the socket (fclose(udpSocket)) AND clean the variables (udpSocket, udpCleaner); otherwise you will run into the “Unsuccessful open: Unrecognized Windows Sockets error: 0: Cannot bind” error.
Note from Aaron:
One note: the onCleanup function/object is designed as a callback of sorts: no matter how the function exits (normally, error, crash, Ctrl-C), when the onCleanup object is automatically then destroyed, its anonymous function should run. Thus, the UDP connection should be closed no matter how you exit the function. This won’t work for a script, though, or if you were just running the code on its own in a command window, as the onCleanup object wouldn’t be automatically destroyed. I would just exclude that line completely if you weren’t running it as a function.