www.mycpu.eu (C) 2017 by Dennis Kuschel 

Networking with MyCPU

Contents:

Overview

With the latest software package MyCPU supports the basic internet networking services Telnet, HTTP and FTP. These services are using the TCP/IP protocol to interconnect with other computers. Because TCP/IP is a bit more complex I didn't wrote the software myself, but I have ported Adam Dunkel's uIP v1.0 to MyCPU instead. The figure below gives an overview of the network software architecture on MyCPU:



With this software I set up a real HTTP web server that serves this website. The server is managed via Telnet and FTP, and the hardware is reduced to the minimum:

      
The MyCPU webserver consists of the components CPU, Interrupt Controller, Memory Unit with extension board, IDE interface with CF-Card and Ethernet Interface Board.


The table below lists the components that are required to run different network services:

  MyCPU
Memory Unit
RS232-Board
MyCPU
Interrupt Controller
Memory Unit
RS232-Board
MyCPU
Interrupt Controller
Memory Unit
Memory Extension
RS232-Board
MyCPU
Interrupt Controller
Memory Unit
Memory Extension
IDE Controller
Ethernet Controller
 basic services (ping) yesyesyesyes
 telnet, http with restrictionsyesyesyes
 ftp nonoyesyes

When no Ethernet interface board is installed, the network connection must be established via the SLIP protocol. In this case the second RS232 port (COM2) of MyCPU is connected to a PC that acts as SLIP gateway. How to configure SLIP on a serial port under WindowsXP is described in this article.



Using network on a minimalist MyCPU computer

This hardware is required:
  • A working MyCPU processor
  • Memory base board with latest software installed
  • RS232 interface board
  • Interrupt controller board
  • Two Null-modem cables
  • A PC with two serial ports (COM1 and COM2)
  • Optional: An old VT100 terminal
With this hardware setup it is possible to run TCP/IP with telnet and http on the MyCPU. You need a working SLIP connection between MyCPU and a PC for IP packet transfer. Connect serial port 2 on the MyCPU RS232 board through a Null-modem cable with a free port on a PC. A USB-RS232-bridge would do also if you do not have a RS232 port on your PC. How to configure SLIP on a Windows XP machine is described in this article.
The link from MyCPU's serial port 2 to the PC will also be used for file transfers in the startup phase. Please follow exactly the steps described here to get the MyCPU network running:
  1. Setup your MyCPU hardware, connect the boards via a flat cable backplane, and connect a power supply to the +5V and GND rails. It is not required to supply the +12V rail on the backplane.
  2. Connect a VT100 compatible terminal with serial port 1 of MyCPU.
  3. Alternatively connect com1 of the PC with port 1 of MyCPU. Run hyperterminal or similar on the PC.
  4. Connect com2 of the PC with serial port 2 of MyCPU.
  5. Download the latest MyCPU software package from the internet.
  6. Unzip the package and run the program server/rfss.exe. Enter "rfss /p2" in a DOS-box to bind rfss to com2:
  7. Switch on the powersupply. MyCPU should boot now. MyCPU will show a boot-menu that was loaded from the PC.
  8. When the menu is displayed choose menu point [3]: boot MyCPU with network support
  9. Configure the IP address for MyCPU. Because DHCP is not supported you must configure a static IP address. Enter "edit /etc/netconfig" on the MyCPU. Scroll down to the line "ipaddress = 192.168.1.33". Change the IP address to the one you have chosen for MyCPU. Leave the editor by pressing F8 and then "Y". Note: If you cannot leave the editor by pressing F8, then press F1 and then 'X'.
  10. Kill the remotefs-service on MyCPU: enter the line "kill remotefs".
  11. Quit the rfss tool on the PC by pressing "X"
  12. Start the network on MyCPU by entering "net start all". You will get the message that FTP could not be started if you do not have the memory extension board installed. That's ok.
  13. Start the SLIP connection on you Windows XP machine. Make sure that you have set the correct parameters for the serial connection. The parameters are: 115200 baud, 8 bits, 1 stopbit, hardware handshake. Important: Use an other IP address for the PC than for the MyCPU. If MyCPU is 192.168.1.33, then use for SLIP 192.168.1.2 (for example). And please disable the Windows firewall on the SLIP connection. Windows should be able to connect to MyCPU now.
  14. Now you should be able to ping the MyCPU. Open a DOS-box on the PC and enter "ping 192.168.1.33" (the MyCPU's internet address).
  15. Also telnet should work. In the DOS-box, enter "telnet 192.168.1.33". The login is "root" and the password is "mycpu". Press [enter] twice to see the prompt.
  16. Now start a webbrowser and enter the URL "http://192.168.1.33". You should see a small website served by your MyCPU!
  17. On MyCPU there are two useful tools you may try: "netstat" displays some network statistics and "ifconfig" shows the actual network configuration. And of course there is also a "ping" on MyCPU available :-)



Using network on a MyCPU with Ethernet card and Harddisk

This hardware is required:
  • A working MyCPU processor
  • Memory base board + extension board with latest software installed
  • RS232 interface board
  • Interrupt controller board
  • IDE controller board with installed harddisk or CF-card
  • Ethernet controller board
  • A Null-modem cable and a crossed Ethernet cable
  • A VT100 terminal or a PC running hyperterm
  • Optional: MyCPU VGA graphic unit and keyboard interface extension card
This is nearly the "gold"-setup for networking with MyCPU. Network startup is fast and easy, and the harddisk has enough space for a bigger website. Here are the steps that are required to get the network up and running:
  1. Setup your MyCPU hardware, connect the boards via a flat cable backplane, and connect a power supply to the +5V and GND rails. It is not required to supply the +12V rail on the backplane.
  2. Connect a VT100 compatible terminal with serial port 1 of MyCPU or use the Video display and keyboard.
  3. Connect MyCPU's ethernet card with a crossed cable to your PC or with a non-crossed cable to a network switch.
  4. Download and install the latest software package on MyCPU's harddisk. To do so, you will need a second serial connection to a PC running the rfss.exe program. You must start remotefs on the MyCPU by entering "remotefs com2: 14:". Change to drive 14: and enter "copy8" to install the update on you harddisk. Hint: A more easy way to install the update is to format drive 8: (enter "format 8:") and then reboot the system. (Before formatting the drive please ensure that the remote-fs connection works properly!).
  5. Configure the IP address for MyCPU. Because DHCP is still not supported you must configure a static IP address. Enter "edit /etc/netconfig" on the MyCPU. Scroll down to the line "ipaddress = 192.168.1.33". Change the IP address to the one you have chosen for MyCPU. Change also the gateway address and the subnet mask. Now scroll up to the line "devicelib = SL25". Change "SL25" to "SL26". SL26 is the driver for the ethernet card. Leave the editor by pressing F8 and then "Y". Note: If you cannot leave the editor by pressing F8, then press F1 and then 'X'.
  6. Start the network on MyCPU by entering "net start all". You may get the message that FTP could not be started if you do not have the memory extension board installed. That's ok.
  7. Now you should be able to ping the MyCPU. Open a DOS-box on the PC and enter "ping 192.168.1.33" (the MyCPU's internet address).
  8. Also telnet should work. In the DOS-box, enter "telnet 192.168.1.33". The login is "root" and the password is "mycpu". Press [enter] twice to see the prompt.
  9. Now start a webbrowser and enter the URL "http://192.168.1.33". You should see a small website served by your MyCPU!
  10. File transfers from and to MyCPU become very easy now: Simply use a FTP client progam to connect to MyCPU! Try it out, open a webbrowser and enter the URL "ftp://192.168.1.33". The login is "root" and the password is "mycpu". Hint: It is a very good idea to use programs like WinSCP, FlashFXP or ftp.exe (DOS box) to transfer files via FTP. The ftp clients that are built into the web browsers aren't so good.
  11. On MyCPU there are three useful tools you may try: "netstat" displays some network statistics, "ifconfig" shows the actual network configuration and "arp" is used to manage the MAC-to-IP-address resolution. And of course there is also a "ping" on MyCPU available :-)
  12. To stop the network on MyCPU, enter "net stop"
  13. You may want to change the default username and password for telnet and ftp. The default words are set in the first lines of the script "net". Type "edit /bin/net" to edit the script.



Networking with MyCPU Emulator

You can try out the networking capabilities of MyCPU by using the MyCPU Emulator. The emulator simulates all available MyCPU hardware on a PC. The emulator is available for MS Windows and Linux. But the network simulation is only implemented under MS Windows. You need: Follow these instructions to get the MyCPU emulation with network running on your PC:
  1. Download the emulator and the packet capture driver. Install the driver on your PC (administrator rights are required)
  2. Check the network configuration of your PC. Your PC should have a static IP address assigned. And the PC must have one active ethernet connection (not wireless or dial-up!) to anywhere (an ethernet switch as remote station is sufficient, a second computer is not required).
  3. Find an unused IP address in your network. You will need this IP for the MyCPU emulator.
  4. Start the MyCPU emulator by double-clicking the file "cpuemu8.exe".
  5. At the MyCPU command prompt enter "edit /etc/netconfig".
  6. Scroll down to the line "ipaddress = 192.168.1.33". Change the IP address to the one you have chosen for MyCPU. Change also the gateway address and the subnet mask.
  7. Leave the editor by pressing F8 and then 'Y'.
  8. Start the network by entering "net start all".
  9. The network will be set up automatically. If you made a mistake while entering the IP addresses, you are required to quit the emulator and restart them again. Repeat the last four steps.
  10. The network should work now. Try to ping your PC from MyCPU (enter "ping aaa.bbb.ccc.ddd" at the prompt, where aaa.bbb.ccc.ddd is the IP address of your PC)
  11. If your PC does not answer the ping you may have a firewall installed that prohibits pings. If so, try to ping the MyCPU emulation from within a DOS box on your PC.
  12. If you still have problems with the network connection, try setting up the interface manually. Start the MyCPU emulator, press [ESC] three times, and then press 'N'. You should get a list with all network adapters installed in your PC. Choose the one that is connected with a cable to a switch or to an other computer. You should get the message that the network is initialized now. Press 'R' to run the emulation, and then type "net start all" to start the network on MyCPU.
  13. The network services Telnet, http and ftp should work now. Open a webbrowser and enter MyCPU's IP address in the address line. The browser should load a small website from the emulator. Telnet and ftp should work also. You need a login name and password for these services: The login is "root", password is "mycpu".
  14. MyCPU knows some networking commands on the command line: Try "netstat", "ifconfig" and "arp".
  15. To stop the network on MyCPU, enter "net stop"



Starting network automatically at MyCPU start up

It is possible to start network services automatically when MyCPU is booted. After power-on the operating system executes the script 8:/init. You can add your own autostart commands there. At the command prompt enter "edit 8:/init". Scroll down to the end of the file and add your lines there:
  • To start the whole network system (http, Telnet and ftp), add the line "call net start all"
  • To start only one or two special services, add one or two of these lines:
       "call net start telnet" (starts telnet)
       "call net start httpd" (starts the http webserver)
       "call net start ftpd" (starts the ftp server)



Description of MyCPU networking programs and tools

  1. net
  2. netstart
  3. httpserv
  4. telserv
  5. ftpd
  6. ifconfig
  7. netstat
  8. ping
  9. arp

Command: net

"net" is a script that is used to start or stop network services. It calls all the other services described in this chapter. The script takes one to four parameters. The syntax is as follows:

  net start|stop [service] [login-name] [password]

        service: Can be "telnet", "httpd" or "ftpd"
        login-name and password: Optional, set login data for telnet and ftpd service.

Most common usage:
  net start all - starts all services
  net stop      - stops all services

The "net" script is stored in 8:/bin/. The default login and password (that is "root" and "mycpu") is hard-coded in the first lines of the script. You can use the editor "edit" to change the default login data in the file.

Command: netstart

"netstart" is a binary program that loads the network libraries into memory. Do not call separately. Use the "net" command to start the network.

Service: httpserv

This program implements the http webserver service. If it is started without any parameter it comes up with a status screen showing the last web accesses. The prgram takes these parameters:

  httpserv [-d] [-g]

     -d   start server as demon in the background
     -g   allow httpserv to offer gzip'd html files. If this parameter is set a copy of all html files must be present
          in gzip'd version in the subdirectory ".gz" (if base html directory is 8:/html, the gzip directory is 8:/html/.gz).
          The gzip'd files must still have the extension ".htm". httpserv will look into the .gz directory first, and if it
          does not find the requested .htm file it will look into the base html directory.

The webserver is configured by the configuration file 8:/bin/httpservcfg

Service: telserv

This is the telnet server. It installs in background and takes over stdin/stdout when a client connects to MyCPU. The telserv demon accepts these parameters:

  telserv [login:password]

     login       login name that must be entered if a client whishes to connect to MyCPU
     password    password that will be asked for at login.

Note: When telserv is loaded it is no more possible to switch into graphics mode. Screen size is also reduced to 80 x 24 characters so every telnet client is capable of displaying the entire screen.

Service: ftpd

This is the ftp server. It installs in background and waits for incomming connections. It can handle multiple ftp transfers in parallel. The prgram takes these parameters:

  ftpd [-u username] [-p password] [rootpath]

     username       is the username that will be asked for at logon
     password       is the password that will be asked for at logon
     rootpath       optional: allow clients only to see a part of the installed disk drives.
                    This parameter specifies a subdirectory that is exported.

When ftpd is started without any parameter, all installed disk drives are exported and no login/password is required on logon. To export only one public folder for anonymous login, use the command "ftpd -u anonymous 8:/public"

Command: ifconfig

The ifconfig tool displays all available information about the current network configuration. The command does not take any parameter.

Command: netstat

The netstat command is used to display network statistics and connection status. The command takes these parameters:

  netstat [-t] [-c]

     -t     show TCP/IP protocol statistics
     -c     show currently established connections and listening ports

netstat will show all availabe information (statistics and connections) when no parameter is given.

Command: ping

This command is used to send an ICMP echo request packet ("ping") to a remote computer. Command syntax:

  ping [-t] [-n count] [-l size] addr

     -t     send pings endlessly. Break with CTRL+C
     -n     set the amount of pings to send. If -n is not set 4 pings are sent.
     -l     set the size of a ping packet. Due to a bug size must be in the range 1..255 (default 32)
     addr   IP address of destination computer

Command: arp

The arp command is only used in conjunction with an Ethernet network card. The command is used to display and manage the table of MAC addresses. "ARP" is a protocol to resolve IP addresses to MAC addresses. The arp command takes these parameters:

  arp [-a] [-s IP MAC] [-d IP]

     -a     displays the contents of the ARP table
     -s     sets an static entry in the ARP table
     -d     deletes an entry from the ARP table

IP: IP-address (notation 0.0.0.0), MAC: MAC-address (notation 00-00-00-00-00-00)




Writing own networking programs in "C"

1. Introduction

Since C-Compiler version 1.6  MyCPU supports a BSD style network socket interface with TCP and UDP connections. Because the MyCPU operating system is not able of doing real multitasking only one thread is allowed doing socket I/O. Thus it is recommended to use sockets in non-blocking mode.

2. How it works

Because a "C" program can only have a size up to 32kb in memory, the socket API layer (also written in "C") is loaded into a separate memory page. When you compile a networking program you must link the library socketslib.lib to your progam. When your program opens a socket the library will load the socket API layer into memory. The socket API is layed out as module and can be found in the /bin/ directory: 8:/bin/sockets.mod.

3. Socket Functions

The MyCPU socket API supports only the most common socket functions.
To use the functions add the line " #include <sockets.h> " to your program.
These functions are available on MyCPU:
These functions are *not* available on MyCPU:
There are some more limitations on MyCPU:
  • RAW sockets are not supported
  • Signals are not supported in conjunction with sockets
  • MyCPU is single threaded, fork() is not supported
  • Most socket options (used with ioctlsocket() and setsockopt()) are not implemented
  • Use ioctlsocket() instead of ioctl() on sockets
  • Standard header files are not supported, only <sockets.h> is available

select2 and timeval
The structure struct timeval is implemented on MyCPU, but the work with this structure is expensive (it consumes lots of CPU cycles). So there is a second version of the select() function available that does not use the timeval structure. The syntax is:

  int select2(int maxfd, fd_set *readset, fd_set *writeset, unsigned *timeout);

The difference to the usual select() function is that the "exceptset" is missing and the timeout value is an unsigned variable that counts with a resolution of CLOCKS_PER_SEC (that is 20 ticks per second on MyCPU). For more information about the usage of select() please see the Linux man page about select().

ioctlsocket
The function ioctl() is named ioctlsocket() on MyCPU. This is to avoid a clash in the C compiler's name space. If you whish to do I/O-control on sockets you must use the function ioctlsocket(). But note that only the I/O commands FIONREAD and FIONBIO are implemented on MyCPU.

4. Programming Examples

Here is an example for a TCP/IP server program. The data transfer works non-blocking. This is done by using the select2()-function to poll the sockets. The program can do other things (like printing nice messages ;-)) while no data is available for receive.
This program works together with the client program beneath. If you do not have two MyCPU's for the test you can also use one or two instances of the MyCPU emulator.

/*
 *   server.c -- a stream socket server demo for MyCPU
 *
 *   Compile with
 *       cl65 -t mycpu server.c socketslib.lib
 */

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <time.h>
#include <sockets.h>

#define PORT     4000  /* the port users will be connecting to */
#define BACKLOG     3  /* how many pending connections queue will hold */

#define READSIZE  100
#define SENDSIZE  100
static char readbuf[READSIZE];  /* buffer for receive data */
static char sendbuf[SENDSIZE];  /* buffer for send data */

int main(void)
{
    fd_set master_set, rd_set;
    struct sockaddr_in servaddr, peeraddr;
    socklen_t slen;
    unsigned timeout;
    int sockfd;   /* server socket */
    int connfd;   /* socket of data connection */
    int ret, n;
    int quit=0;

    /* create new TCP socket */
    sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd < 0) {
        perror("socket()");
        exit(1);
    }

    /* bind socket to server port */
    memset(&servaddr, 0, sizeof(servaddr));
    servaddr.sin_family      = AF_INET;
    servaddr.sin_addr.s_addr = INADDR_ANY;
    servaddr.sin_port        = htons(PORT);
    ret = bind(sockfd, (struct sockaddr *)&servaddr, sizeof(servaddr));
    if (ret < 0) {
        perror("bind()");
        close(sockfd);
        exit(1);
    }

    /* set socket to listen mode */
    ret = listen(sockfd, BACKLOG);
    if (ret < 0) {
        perror("listen()");
        close(sockfd);
        exit(1);
    }

    /* prepare for select() */
    FD_ZERO(&master_set);
    FD_SET(sockfd, &master_set);
    connfd = -1;

    /* handle connections in an endless loop */
    while (!quit)
    {
        /* check for incomming connections and data by polling the sockets with select() */
        timeout = 5;  /* 5 x 50ms = 250ms. timeout can also be set to 0 */
        rd_set = master_set;
        n = select2(FD_SETSIZE+1, &rd_set, NULL, &timeout);
        if (n < 0) {
            perror("select()");
            close(sockfd);
            exit(1);
        }

        /* Timeout or nothing to do? -> Print message while we are idle. */
        if (n == 0) {
            printf("(clock %lu) Press any key to quit or connect to port %i\r", clock(), PORT);
            if (kbhit()) {
                cgetc();
                printf("\nQuit\n");
                quit = 1;
            }
        }

        /* Is a socket ready for read? */
        if (n > 0) {
            if (FD_ISSET(sockfd, &rd_set)) {
                /* It is the server socket. Somebody wants to connect to us. */
                /* Close other connection if established. */
                if (connfd >= 0) {
                    FD_CLR(connfd, &master_set);
                    close(connfd);
                }
                /* get new connection socket */
                slen = sizeof(peeraddr);
                connfd = accept(sockfd, (struct sockaddr *)&peeraddr, &slen);
                if (connfd >= 0) {
                    /* add new connection to master_set so select() will look at it */
                    FD_SET(connfd, &master_set);
                    /* print connection data */
                    printf("\n\nGot new connection from IP %s, port %u\n",
                           inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
                    /* send a welcome message to our peer */
                    sprintf(sendbuf, "Welcome! Server time is %lu ticks.", clock());
                    toascii(sendbuf, sendbuf); /* on MyCPU: convert character set */
                    write(connfd, sendbuf, strlen(sendbuf));
                }
            }
            else
            {
                /* Any other socket is ready for read. Check if it is the connection socket. */
                if ((connfd >= 0) && FD_ISSET(connfd, &rd_set)) {
                    /* there is incomming data on the connection */
                    ret = read(connfd, readbuf, READSIZE-1);
                    if (ret < 0) {
                        /* we lost the connection */
                        printf("\nLost connection to IP %s, port %u\n",
                               inet_ntoa(peeraddr.sin_addr), ntohs(peeraddr.sin_port));
                        FD_CLR(connfd, &master_set);
                        close(connfd);
                        connfd = -1;
                    } else {
                        /* print out the received data */
                        readbuf[ret] = 0;
                        topetscii(readbuf, readbuf); /* on MyCPU: convert character set */
                        printf("\nreceived %i bytes: \"%s\"\n", ret, readbuf);
                    }
                }
            }
        }
    }

    /* cleanup and exit */
    close(sockfd);
    if (connfd >= 0) {
        close(connfd);
    }

    return 0;
}

Below is an example for a TCP/IP client program. It works, like the server program above, in non-blocking mode by using the select2()-function to poll the sockets.

/*
 *   client.c -- a stream socket client demo for MyCPU
 *
 *   Compile with
 *       cl65 -t mycpu client.c socketslib.lib
 */

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <time.h>
#include <sockets.h>

#define PORT     4000  /* the port users will be connecting to */
#define BACKLOG     3  /* how many pending connections queue will hold */

#define READSIZE  100
#define SENDSIZE  300
static char readbuf[READSIZE];  /* buffer for receive data */
static char sendbuf[SENDSIZE];  /* buffer for send data */

int main(int argc, char *argv[])
{
    fd_set master_set, rd_set;
    struct sockaddr_in addr;
    unsigned timeout;
    int sockfd;
    int ret, n;
    int i=0, quit=0;

    if (argc != 5) {
        printf("Usage: %s ServerIP word1 word2 word3\n", argv[0]);
        printf("Example: %s 192.168.1.33 Hello beautiful world\n", argv[0]);
        return 1;
    }

    /* create new TCP socket */
    sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockfd < 0) {
        perror("socket()");
        exit(1);
    }

    /* connect socket to server */
    memset(&addr, 0, sizeof(addr));
    addr.sin_family      = AF_INET;             /* AF_INET means "Internet Protocol */
    addr.sin_addr.s_addr = inet_addr(argv[1]);  /* convert IP address to binary number */
    addr.sin_port        = htons(PORT);         /* set server port number */
    printf("Connecting to %s ... ", inet_ntoa(addr.sin_addr));
    ret = connect(sockfd, (struct sockaddr*)&addr, sizeof(addr));
    if (ret < 0) {
        perror("connect() failed");
        close(sockfd);
        exit(1);
    }
    printf("ok.\n");

    /* prepare for select() */
    FD_ZERO(&master_set);
    FD_SET(sockfd, &master_set);

    /* handle the TCP/IP connection */
    while (!quit)
    {
        /* check for incomming data polling the socket with select() */
        timeout = 20;  /* 20 x 50ms = 1s */
        rd_set = master_set;
        n = select2(FD_SETSIZE+1, &rd_set, NULL, &timeout);
        if (n < 0) {
            perror("select()");
            close(sockfd);
            exit(1);
        }

        /* Timeout? -> Send next message to server */
        if (n == 0) {
            printf("sending \"%s\"\n", argv[i+2]);
            toascii(sendbuf, argv[i+2]); /* on MyCPU: convert character set */
            ret = write(sockfd, sendbuf, strlen(sendbuf));
            if (ret < 0) {
                perror("write() - connection lost!");
                close(sockfd);
                exit(1);
            }
            if (++i >= 3)
                quit = 1;
        }

        /* Is a socket ready for read? */
        if (n > 0) {
            if (FD_ISSET(sockfd, &rd_set)) {
                /* read data from our socket */
                ret = read(sockfd, readbuf, READSIZE-1);
                if (ret < 0) {
                    perror("read() - connection lost!");
                    close(sockfd);
                    exit(1);
                }
                if (ret > 0) {
                    readbuf[ret] = 0;
                    topetscii(readbuf, readbuf); /* on MyCPU: convert character set */
                    printf("received %i bytes: \"%s\"\n", ret, readbuf);
                }
            }
        }
    }

    /* cleanup and exit */
    close(sockfd);
    return 0;
}


These two pictures are showing the programs running in two instances of the MyCPU Emulator:






5. External Links

Introduction to TCP/IP and sockets (pdf)
Programming UNIX Sockets in C (FAQ)
Beej's Guide to Network Programming
Linux man page about sockets