Computer Labs 2013/2014 - 1st Semester
Project: Serial Communication on I304


1. Introduction

This note is about how to set up an environment that allows communication between two virtual machines (VM) running on different PCs via the virtual serial ports.

This setup is useful for virtually all projects that use the serial port. Indeed, most of you are developing games and it is not enough to connect two VMs on the same PC. This is because you usually need both instances of your application to respond to input from either the keyboard or the mouse. It turns out that you can have the focus on only one VM, therefore you cannot generate input events to one VM, while the focus is on the other. If in the multi-user version application you plan to develop, users can take turns, this is not so problematic. Otherwise, running two VMs on the same PC will not work.

2. Solution

A solution to this problem is to use an utility named socat. This is a rather powerful tool, that allows to set up "communication channels" between different types of data sinks and sources.

Actually, the idea is not very different from the one used to interconnect two VMs in the same computer using (Unix domain) sockets. Figure 1(i) illustrates how the serial ports of 2 VMs running on the same computer can be connected using Unix domain sockets.

Fig1: Connecting the serial ports of two VMs.
Fig. 1(i) Fig. 1(ii)
(i) VMs on the same computer.(ii) VMs on different computers connected via a network.

The problem with Unix domain sockets is that they allow communication only between processes in the same computer. However, VMwarePlayer does not allow to connect the serial port to other types of sockets. Thus, we will use socat as shown in Figure 1(ii). Basically, the communication channel between the two VMs is now composed of: a network connection between 2 socat processes, each of which running on a different computer, these two (socat) processes and the 2 Unix domain sockets connecting each socat to the VM running on the same computer.

3. Setup

To setup this "communication channel", you need to configure the serial ports of the two VM appropriately, and invoke the socat utility in each computer with the appropriate parameters.

3.1 VMwarePlayer

To simplify, configure the serial ports of both VMs identically:

3.2 socat

Each instance of the socat utility has to be invoked with different command line arguments, but if you configured the same name for the (Unix domain) socket the differences are minor.

On a terminal of one of the computers, execute socat as follows:

socat TCP-LISTEN:4567 UNIX-CONNECT:/tmp/vm

Note that the string after "UNIX-CONNECT" is the name of the socket you set in VMwarePlayer. The number after "TCP-LISTEN" is known as the TCP port. It must be a number larger than 1023 and smaller 65636. Whatever the number you choose, you will need it for running socat on the second computer. In addition, you need also to find the IP address of this (first) computer. You can find it by executing the command ifconfig. The output will look as follows:

$ ifconfig eth0 Link encap:Ethernet HWaddr 00:21:5d:62:78:82 inet addr:172.30.9.196 Bcast:172.30.255.255 Mask:255.255.0.0 inet6 addr: 2001:690:2200:9a77:221:5dff:fe62:7882/64 Scope:Global inet6 addr: fe80::221:5dff:fe62:7882/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:23303302 errors:0 dropped:4 overruns:0 frame:0 TX packets:451083 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:3831961730 (3.8 GB) TX bytes:108440744 (108.4 MB) lo Link encap:Local Loopback inet addr:127.0.0.1 Mask:255.0.0.0 inet6 addr: ::1/128 Scope:Host UP LOOPBACK RUNNING MTU:16436 Metric:1 RX packets:26131 errors:0 dropped:0 overruns:0 frame:0 TX packets:26131 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:0 RX bytes:16152047 (16.1 MB) TX bytes:16152047 (16.1 MB) vmnet1 Link encap:Ethernet HWaddr 00:50:56:c0:00:01 inet addr:192.168.184.1 Bcast:192.168.184.255 Mask:255.255.255.0 inet6 addr: fe80::250:56ff:fec0:1/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:0 errors:0 dropped:0 overruns:0 frame:0 TX packets:261 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B) vmnet8 Link encap:Ethernet HWaddr 00:50:56:c0:00:08 inet addr:172.16.55.1 Bcast:172.16.55.255 Mask:255.255.255.0 inet6 addr: fe80::250:56ff:fec0:8/64 Scope:Link UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1 RX packets:10247 errors:0 dropped:0 overruns:0 frame:0 TX packets:10322 errors:0 dropped:0 overruns:0 carrier:0 collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)

The IP addresss is the field inet addr of the eth0 interface. (Assuming you are using the PCs in the I304. If you are testing via a wireless connection, the network inteface will likely be named wlan0.) Therefore, in this example, the IP address of the first computer is 172.30.9.196. (You may also find the IP address, using a GUI. Just start SystemSettings, and select the network icon.)

You can now execute socat on a terminal of the other computer as follows:

socat TCP-CONNECT:172.30.9.196:4567 UNIX-CONNECT:/tmp/vm

The first string, TCP-CONNECT:172.30.9.196:4567, specifies where the remote socat can be found. The second string, UNIX-CONNECT:/tmp/vm, specifies the Unix domain socket to which the serial port of the VM is connected. You can change the order of these "addresses", if you wish. On the other hand, by the time you start this socat instance (which uses the "TCP-CONNECT" address), the other one (which uses a "TCP-LISTEN" address) must be already running.

3.3 Testing

You can test your setup, by running on the VMs either the code you have developed for Lab 7, or the test program I have provided. You should be able to exchange data in both directions by invoking the test programs with the appropriate arguments.