# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
#
# this file can be found at www.estss.com/opensource/cheatsheet.php
#
#
# this file covers the network sockets (open read write close)
# (both peer2peer and multi-users) in the following languages:
# - C/C++
# - C#
# - Java
# - Perl
# - Python
# - Ruby
#
# note: all programs/scripts can be tested from one language to any other one.
#       this helps to show that the codes are language (platform) independent...
#       tcp peer2peer will run on port 50000
#       udp peer2peer will run on port 51000
#       and tcp multi-users will run on port 52000
#
# note: select() was chosen to provide "asynchronous" like behavior.
#       threading is possible to provide the same feature, but select()
#       is one popular use in socket programming.  some programming
#       languages have different functionality with select() which will
#       be noted in this file (hence the cheatsheets).
#       threaded programming may show up in another cheatsheet/notes file...
#
#
# best viewed in editor with tab stops set to 4
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# C/C++ {{{
# --------------------------------------------------------------------------------

| C/C++ | C# | Java | Perl | Python | Ruby |



----- begin c_cpp_network.c -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// note: there are plenty of berkley socket programming information out there.
// and these are my cheat sheets.  so, as such, when i program c/c++ networking
// i normally use the SDL_net library.  <snip giant explaination about what i
// use it for and why, cross platform issues, how the other languages are fairly
// platform agnostic, etc. etc. etc...>

// and to be even lazier about this, go here...
// http://gpwiki.org/index.php/SDL:Tutorial:Using_SDL_net

----- endof c_cpp_network.c -----


# C/C++ }}}
# C# {{{
# --------------------------------------------------------------------------------



| C/C++ | C# | Java | Perl | Python | Ruby |


# TCP
# http://codeidol.com/csharp/csharp-network/Csharp-Network-Programming-Classes/Csharp-Socket-Programming/
# ........................................



----- begin csharp_tcp_server.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_tcp_server.cs
 *  # the file csharp_tcp_server.exe is created
 * 
 * to run:
 *     mono csharp_tcp_server.exe
 *  # or
 *  ./csharp_tcp_server.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: TCP echo server
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException

class Csharp_tcp_server
{
    public static void Main( string[] args ) {
        string host = "localhost";
        int port = 50000;
        int backlog = 5;
        int maxsize = 1024;

// if host has more than one NIC/IPaddresses
        IPHostEntry results = Dns.GetHostByName( host );
        IPAddress addr = results.AddressList[0];
//      IPAddress addr = IPAddress.Parse( "127.0.0.1" );
//      IPEndPoint iep = new IPEndPoint( IPAddress.Any, port );
        IPEndPoint iep = new IPEndPoint( addr, port );

        Socket sock;
        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " + e.ToString() );
            return;
        }
        try {
            sock.Bind( iep );
            sock.Listen( backlog );
        } catch( SocketException e ) {
            Console.WriteLine( "unable to bind to port: {0} {1}", port, e.ToString() );
            return;
        }
        Console.WriteLine( "server started on port " + port );

        byte[] msg = new byte[maxsize];
        while ( true ) {
            Socket client = sock.Accept();                  // blocking
            IPEndPoint client_iep = (IPEndPoint)client.RemoteEndPoint;
            string laddr = client_iep.ToString();

            if ( client.Receive( msg, maxsize, 0 ) != 0 ) { // blocking
                Console.WriteLine( "connection from: {0} {1}", laddr, Encoding.ASCII.GetString( msg ) );
                client.Send( msg );         // sends even on a broken socket
                // csharp specific function that throws on error...
                // to "gracefully" shutdown buffers: in this case both Receive & Send
                try { client.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
            } else
                Console.WriteLine( "lost connection on recv: " + laddr );
            client.Close();
    }   }
}

----- endof csharp_tcp_server.cs -----


# ........................................



----- begin csharp_tcp_client.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_tcp_client.cs
 *  # the file csharp_tcp_client.exe is created
 * 
 * to run:
 *     mono csharp_tcp_client.exe
 *  # or
 *  ./csharp_tcp_client.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: TCP echo client
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException

class Csharp_tcp_client
{
    public static void Main( string[] args ) {
        string host = "localhost";
        int port = 50000;
        int maxsize = 1024;

        Socket sock;
        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " + e.ToString() );
            return;
        }
        IPHostEntry results = Dns.GetHostByName( host );
        IPEndPoint iep = new IPEndPoint( results.AddressList[0], port );
        try { sock.Connect( iep ); }
        catch( SocketException e ) {
            Console.WriteLine( "unable to connect to {0}:{1} {2}", host, port, e.ToString() );
            return;
        }
        Console.WriteLine( "connected to server, sending msg..." );

        sock.Send( Encoding.ASCII.GetBytes( "Howdy" ) );    // sends even on a broken socket

        Console.WriteLine( "server response:" );
        byte[] msg = new byte[maxsize];
        if ( sock.Receive( msg, maxsize, 0 ) != 0 ) {       // blocking
            Console.WriteLine( "Received " + Encoding.ASCII.GetString( msg ) );
            // csharp specific function that throws on error...
            // to "gracefully" shutdown buffers: in this case both Receive & Send
            try { sock.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
        } else
            Console.WriteLine( "lost connection on recv" );
        sock.Close();
    }
}

----- endof csharp_tcp_client.cs -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# UDP
# http://www.java2s.com/Code/CSharp/Network/SimpleUdpServer.htm
# ........................................



----- begin csharp_udp_server.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_udp_server.cs
 *  # the file csharp_udp_server.exe is created
 * 
 * to run:
 *     mono csharp_udp_server.exe
 *  # or
 *  ./csharp_udp_server.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: UDP echo server
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException

class Csharp_udp_server
{
    public static void Main( string[] args ) {
        string host = "localhost";
        int port = 51000;
        int maxsize = 1024;

        IPHostEntry results = Dns.GetHostByName( host );
        IPEndPoint iep = new IPEndPoint( results.AddressList[0], port );
        Socket sock;
        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " + e.ToString() );
            return;
        }
        try { sock.Bind( iep ); }
        catch( SocketException e ) {
            Console.WriteLine( "unable to bind to port: {0} {1}", port, e.ToString() );
            return;
        }
        Console.WriteLine( "server started on port " + port );

        byte[] msg = new byte[maxsize];
        IPEndPoint remote_iep = new IPEndPoint( IPAddress.Any, 0 );
        EndPoint remote_ep = (EndPoint)(remote_iep);
        while ( true ) {
            int recv = sock.ReceiveFrom( msg, ref remote_ep );  // blocking
            if ( recv != 0 ) {
                Console.WriteLine( "msg from: {0} {1}", remote_ep.ToString(),
                                    Encoding.ASCII.GetString( msg, 0, recv ) );
                sock.SendTo( msg, recv, SocketFlags.None, remote_ep );
            } else
                Console.WriteLine( "empty msg from: " + remote_ep.ToString() );
    }   }
}

----- endof csharp_udp_server.cs -----


# http://www.java2s.com/Code/CSharp/Network/UdpClientSample.htm
# ........................................



----- begin csharp_udp_client.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_udp_client.cs
 *  # the file csharp_udp_client.exe is created
 * 
 * to run:
 *     mono csharp_udp_client.exe
 *  # or
 *  ./csharp_udp_client.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: UDP echo client
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException

class Csharp_udp_client
{
    public static void Main( string[] args ) {
        string host = "localhost";
        int port = 51000;
        int maxsize = 1024;
        byte[] msg = new byte[maxsize];

        UdpClient sock;
        try { sock = new UdpClient( host, port ); }
        catch( SocketException e ) {
            Console.WriteLine( "socket error: " + e.ToString() );
            return;
        }
        Console.WriteLine( "sending msg to server..." );

        msg = Encoding.ASCII.GetBytes( "Howdy" );
        sock.Send( msg, msg.Length );

        Console.WriteLine( "server response:" );
        IPEndPoint remote_iep = new IPEndPoint( IPAddress.Any, port );
        msg = sock.Receive( ref remote_iep );               // blocking
        sock.Close();
        // note, this msg may not have come from the "server"
        if ( msg.Length != 0 )
            Console.WriteLine( "msg from {0} {1}", remote_iep.ToString(),
                                Encoding.ASCII.GetString( msg, 0, msg.Length ) );
        else
            Console.WriteLine( "empty msg from:", remote_iep.ToString() );
    }
}

----- endof csharp_udp_client.cs -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# SELECT
# http://codeidol.com/csharp/csharp-network/Csharp-Network-Programming-Classes/Csharp-Socket-Programming/#254
# WARNING: CSHARP Select() HAS A TIMEOUT PARAMETER THAT CANNOT BE SET TO "forever"
#          which means it acts more like poll() -- so using threads...
# ........................................



----- begin csharp_tcp_server_select.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_tcp_server_select.cs
 *  # the file csharp_tcp_server_select.exe is created
 * 
 * to run:
 *     mono csharp_tcp_server_select.exe
 *  # or
 *  ./csharp_tcp_server_select.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: TCP chat server with select()
// entering ANY line of input will exit the server
// -- and yes, this is technically a blocking threaded server solution...
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException Select
using System.Threading;     // Thread
using System.Collections;   // ArrayList

class ClientWatcher
{
    private static ArrayList clients;
    public Socket client;
    public IPEndPoint iep;
    public Thread thread;

    public ClientWatcher( Socket c, ref ArrayList l ) {
        client = c;
        clients = l;
        clients.Add( this );
        iep = (IPEndPoint)c.RemoteEndPoint;

        thread = new Thread( new ThreadStart( this.run ) );
        thread.Start();
    }

    private void run() {
        int maxsize = 1024;
        byte[] data = new byte[maxsize];

        string tosend;
        int size;
        while ( true ) {
            try { size = client.Receive( data, maxsize, 0 ); }  // blocking
            catch( SocketException ) { size = 0; }
            if ( size != 0 ) {
                string msg = Encoding.ASCII.GetString( data );
                tosend = "msg from " + iep.ToString() + " " + msg;
                echo_and_send_to_clients( tosend );
                continue;
            }
            // csharp specific function that throws on error...
            // to "gracefully" shutdown buffers: in this case both Receive & Send
            try { client.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
            client.Close();
            clients.Remove( this );
            tosend = "client leaving: " + iep.ToString();
            echo_and_send_to_clients( tosend );
            return;
    }   }

    public void echo_and_send_to_clients( string tosend ) {
        byte[] data = Encoding.ASCII.GetBytes( tosend );
        Console.WriteLine( tosend );
        foreach( ClientWatcher c in clients )
            c.client.Send( data );          // sends even on a broken socket
    }
}

class Csharp_tcp_server_select
{
    private Socket sock;
    private ArrayList clients = new ArrayList();

    public static void Main( string[] args ) {
        Csharp_tcp_server_select demo = new Csharp_tcp_server_select();
        demo.csharp_tcp_server_select();
    }

    public void csharp_tcp_server_select() {
        string host = "localhost";
        int port = 52000;
        int backlog = 5;

        IPHostEntry results = Dns.GetHostByName( host );
        IPEndPoint iep = new IPEndPoint( results.AddressList[0], port );
        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " );
            Console.WriteLine( e.ToString() );
            return;
        }
        try {
            sock.Bind( iep );
            sock.Listen( backlog );
        } catch( SocketException e ) {
            Console.WriteLine( "unable to bind to port: " + port );
            Console.WriteLine( e.ToString() );
            return;
        }
        Console.WriteLine( "server started on port " + port );

        // Select() does NOT return a list of ready to read objects...
        // so, spin off threads to prevent main loop from being blocked.
        Thread networkThread = new Thread( networkWatcher );
        networkThread.Start();

        // think of the following as the main loop...
        Console.ReadLine();                                 // blocking

        Console.WriteLine( "shutting down server..." );
        // terminate any live threads -- or else program keeps running...
        networkThread.Abort();
        foreach( ClientWatcher c in clients ) {
            // csharp specific function that throws on error...
            // to "gracefully" shutdown buffers: in this case both Receive & Send
            try { c.client.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
            c.client.Close();
            c.thread.Abort();
        }

        sock.Shutdown( SocketShutdown.Both );               // both: Receive & Send buffers
        sock.Close();
    }

    private void networkWatcher() {
        while ( true ) {
            Socket client;
            try { client = sock.Accept(); }                 // blocking
            catch { return; }   // catch all: chances are, server is shutting down now...
            ClientWatcher c = new ClientWatcher( client, ref clients );
            string tosend = "connection from: " + c.iep.ToString();
            c.echo_and_send_to_clients( tosend );
    }   }
}

----- endof csharp_tcp_server_select.cs -----


# ........................................



----- begin csharp_tcp_client_select.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_tcp_client_select.cs
 *  # the file csharp_tcp_client_select.exe is created
 * 
 * to run:
 *     mono csharp_tcp_client_select.exe
 *  # or
 *  ./csharp_tcp_client_select.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: TCP chat client with select()
// entering ANY line of input will exit the server
// try this with more than one client...
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException /* -Select */
using System.Threading;     // Thread

class Csharp_tcp_client_select
{
    private bool running = true;
    private Socket sock;

    public static void Main( string[] args ) {
        Csharp_tcp_client_select demo = new Csharp_tcp_client_select();
        demo.csharp_tcp_client_select();
    }

    public void csharp_tcp_client_select() {
        string host = "localhost";
        int port = 52000;

        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " + e.ToString() );
            return;
        }
        IPHostEntry results = Dns.GetHostByName( host );
        IPEndPoint iep = new IPEndPoint( results.AddressList[0], port );
        try { sock.Connect( iep ); }
        catch( SocketException e ) {
            Console.WriteLine( "unable to connect to {0}:{1} {2}", host, port, e.ToString() );
            return;
        }
        Console.WriteLine( "connected to server" );

        Console.Write( "% " );
        Console.Out.Flush();

        // Select() does NOT return a list of "ready to read" objects...
        // instead, sockets (which needs to be set to non-blocking)
        // needs to be polled for any data.
        //
        // also, keyboard (STDIN) cannot be added to the (polling) ArrayList
        // or else, during ReadLine() will block...
        // so, spin off threads to prevent main loop from being blocked.
        Thread networkThread = new Thread( networkWatcher );
        networkThread.Start();
        Thread keyboardThread = new Thread( keyboardWatcher );
        keyboardThread.Start();

//      ArrayList input = new ArrayList();
//      input.add( sock );
//      input.add( STDIN... );

        while ( running ) {
// NOTE: csharp Select() acts more like poll()
//          Socket.Select( input, null, null, 1000 );
            Thread.Sleep( 100 );        // meh...
        }

        // terminate any live threads -- or else program keeps running...
        networkThread.Abort();
        keyboardThread.Abort();

        // csharp specific function that throws on error...
        // to "gracefully" shutdown buffers: in this case both Receive & Send
        try { sock.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
        sock.Close();
    }

    private void networkWatcher() {
        int maxsize = 1024;
        byte[] data = new byte[maxsize];
        int size;
        while ( true ) {
            try { size = sock.Receive( data, maxsize, 0 ); }    // blocking
            catch( SocketException ) { size = 0; }
            if ( size != 0 ) {
                Console.WriteLine( Encoding.ASCII.GetString( data ) );
                Console.Write( "% " );
                Console.Out.Flush();
                continue;
            }
            Console.WriteLine( "server has left the building..." );
            running = false;
            return;
    }   }

    private void keyboardWatcher() {
        while ( true ) {
            string msg = Console.ReadLine();                // blocking
            msg = msg.Replace("\n","").Replace("\r","");    // chomp( msg );
            if ( msg.Length != 0 ) {
                sock.Send( Encoding.ASCII.GetBytes( msg ) );    // sends even on a broken socket
                continue;
            }
            Console.WriteLine( "leaving..." );
            running = false;
            return;
    }   }
}

----- endof csharp_tcp_client_select.cs -----


# csharp's alternative "asynchronous" functionality uses CALLBACK mechanisms:
# http://codeidol.com/csharp/csharp-network/Asynchronous-Sockets/Sample-Programs-Using-Asynchronous-Sockets/
# ........................................



----- begin csharp_tcp_server_select_alt.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_tcp_server_select_alt.cs
 *  # the file csharp_tcp_server_select_alt.exe is created
 * 
 * to run:
 *     mono csharp_tcp_server_select_alt.exe
 *  # or
 *  ./csharp_tcp_server_select_alt.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: TCP chat server with select() alternative...
// entering ANY line of input will exit the server
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException
using System.Threading;     // Thread
using System.Collections;   // ArrayList

class Csharp_tcp_server_select_alt
{
    private bool running = true;
    private Socket sock;
    private ArrayList clients = new ArrayList();
    private static int maxsize = 1024;
    private byte[] data = new byte[maxsize];

    public static void Main( string[] args ) {
        Csharp_tcp_server_select_alt demo = new Csharp_tcp_server_select_alt();
        demo.csharp_tcp_server_select_alt();
    }

    public void csharp_tcp_server_select_alt() {
        string host = "localhost";
        int port = 52000;
        int backlog = 5;

        IPHostEntry results = Dns.GetHostByName( host );
        IPEndPoint iep = new IPEndPoint( results.AddressList[0], port );
        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " + e.ToString() );
            return;
        }
        try {
            sock.Bind( iep );
            sock.Listen( backlog );
        } catch( SocketException e ) {
            Console.WriteLine( "unable to bind to port: {0} {1}", port, e.ToString() );
            return;
        }
        sock.BeginAccept( new AsyncCallback( AcceptConn ), sock );
        Console.WriteLine( "server started on port " + port );

        // think of the following as the main loop...
        Console.ReadLine();                                 // blocking

        running = false;
        Console.WriteLine( "shutting down server..." );
        foreach( Socket c in clients ) {
            // csharp specific function that throws on error...
            // to "gracefully" shutdown buffers: in this case both Receive & Send
            try { c.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
            c.Close();
        }
        sock.Shutdown( SocketShutdown.Both );               // both: Receive & Send buffers
        sock.Close();
    }

    private void AcceptConn( IAsyncResult iar ) {
        Socket socky = (Socket)iar.AsyncState;  // note: socky == this.sock
        Socket client = socky.EndAccept(iar);
        if ( running == false )
            return;

        clients.Add( client );
        IPEndPoint client_iep = (IPEndPoint)client.RemoteEndPoint;
        string tosend = "connection from: " + client_iep.ToString();
        echo_and_send_to_clients( tosend );

        client.BeginReceive( data, 0, maxsize, SocketFlags.None,
                    new AsyncCallback( ReceiveData ), client );

        // "loop" back to this function
        socky.BeginAccept( new AsyncCallback( AcceptConn ), socky );
    }

    private void ReceiveData( IAsyncResult iar ) {
        Socket client;
        int recv;
        string msg;
        lock ( data ) { // jic
            client = (Socket)iar.AsyncState;
            recv = client.EndReceive(iar);
            msg = ( recv <= 0 ) ? "" : Encoding.ASCII.GetString( data, 0, recv );
        }
        if ( running == false )
            return;

        IPEndPoint client_iep = (IPEndPoint)client.RemoteEndPoint;
        if (recv <= 0) {
            string tosend = "client leaving: " + client_iep.ToString();
            clients.Remove( client );
            // csharp specific function that throws on error...
            // to "gracefully" shutdown buffers: in this case both Receive & Send
            try { client.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
            client.Close();
            echo_and_send_to_clients( tosend );
        } else {
            string tosend = "msg from " + client_iep.ToString() + " " + msg;
            echo_and_send_to_clients( tosend );
            // "loop" back to this function
            client.BeginReceive( data, 0, maxsize, SocketFlags.None,
                        new AsyncCallback( ReceiveData ), client );
    }   }

    private void echo_and_send_to_clients( string tosend ) {
        Console.WriteLine( tosend );
        byte[] datamsg = Encoding.ASCII.GetBytes( tosend );
        foreach( Socket c in clients )
            // sends even on a broken socket
            c.BeginSend( datamsg, 0, datamsg.Length, SocketFlags.None,
                        new AsyncCallback( SendData ), c );
    }

    private void SendData(IAsyncResult iar) {
        Socket client = (Socket)iar.AsyncState;
        /* int sent = */ client.EndSend(iar);
        // do something here after send was "successful"
    }
}

----- endof csharp_tcp_server_select_alt.cs -----


# ........................................



----- begin csharp_tcp_client_select_alt.cs -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     mcs csharp_tcp_client_select_alt.cs
 *  # the file csharp_tcp_client_select_alt.exe is created
 * 
 * to run:
 *     mono csharp_tcp_client_select_alt.exe
 *  # or
 *  ./csharp_tcp_client_select_alt.exe
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// csharp: TCP chat client with select() alternative...
// entering ANY line of input will exit the server
// try this with more than one client...
using System;               // Console
using System.Text;          // Encoding
using System.Net;           // IPHostEntry IPEndPoint 
using System.Net.Sockets;   // Socket SocketException
using System.Threading;     // Thread

class Csharp_tcp_client_select_alt
{
    private bool running = true;
    private Socket sock;
    private static int maxsize = 1024;
    private byte[] data = new byte[maxsize];

    public static void Main( string[] args ) {
        Csharp_tcp_client_select_alt demo = new Csharp_tcp_client_select_alt();
        demo.csharp_tcp_client_select_alt();
    }

    public void csharp_tcp_client_select_alt() {
        string host = "localhost";
        int port = 52000;

        try {
            sock = new Socket( AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp );
        } catch( SocketException e ) {
            Console.WriteLine( "socket error: " );
            Console.WriteLine( e.ToString() );
            return;
        }

        IPHostEntry results = Dns.GetHostByName( host );
        IPEndPoint iep = new IPEndPoint( results.AddressList[0], port );
        // WARNING: this call will NOT error out or time out if server port is not opened...
        // need to make a "timer" to watch for this... meh...
        sock.BeginConnect( iep, new AsyncCallback( Connected ), sock );

        // spin off thread to prevent main loop from being blocked.
        Thread keyboardThread = new Thread( keyboardWatcher );
        keyboardThread.Start();

// uncomment the following to handle "BeginConnect" issue properly...
//      int timer = 2000;
//      while ( ! sock.Connected ) {    // see warning note above for this check...
//          Thread.Sleep( 100 );
//          timer -= 100;
//          if ( timer < 0 ) {
//              Console.WriteLine( "time out: Connection Refused" );
//              running = false;
//              break;
//      }   }

        while ( running ) {
            Thread.Sleep( 100 );        // meh...
// uncomment the following to handle "BeginReceive" issue properly...
//          if ( ! sock.Connected )     // see warning note in ReceivedData() for this check...
//              networkServerDown();
        }

        // terminate any live threads -- or else program keeps running...
        keyboardThread.Abort();

        // csharp specific function that throws on error...
        // to "gracefully" shutdown buffers: in this case both Receive & Send
        try { sock.Shutdown( SocketShutdown.Both ); } catch( SocketException ){}
        sock.Close();
    }

    private void networkServerDown() {
        Console.WriteLine( "server has left the building..." );
        running = false;
    }

    private void Connected( IAsyncResult iar ) {
        Socket socky = (Socket)iar.AsyncState;              // note: socky == sock
        try { socky.EndConnect(iar); }
        catch ( SocketException ) {
            Console.WriteLine( "unable to connect to {0}", socky.RemoteEndPoint.ToString() );
            running = false;
            return;
        }
        Console.WriteLine( "connected to server" );
        Console.Write( "% " );
        Console.Out.Flush();
        socky.BeginReceive( data, 0, maxsize, SocketFlags.None,
                    new AsyncCallback( ReceiveData ), socky );
    }

    private void ReceiveData( IAsyncResult iar ) {
        // WARNING: if connection terminates abnormally, this function will never be awaken...
        Socket socky;
        int recv;
        string msg;
        lock ( data ) {
            socky = (Socket)iar.AsyncState;                 // note: socky == sock
            recv = socky.EndReceive(iar);
            msg = ( recv <= 0 ) ? "" : Encoding.ASCII.GetString( data, 0, recv );
        }
        if ( running == false )
            return;

        if ( recv <= 0 ) {
            networkServerDown();
            return;
        }
        Console.WriteLine( msg );
        Console.Write( "% " );
        Console.Out.Flush();
        // "loop" back to this function
        socky.BeginReceive( data, 0, maxsize, SocketFlags.None,
                    new AsyncCallback( ReceiveData ), socky );
    }

    private void keyboardWatcher() {
        byte[] datamsg;
        while ( true ) {
            string msg = Console.ReadLine();                // blocking
            msg = msg.Replace("\n","").Replace("\r","");    // chomp( msg );
            if ( msg.Length == 0 ) {
                Console.WriteLine( "leaving..." );
                running = false;
                return;
            }
            datamsg = Encoding.ASCII.GetBytes( msg );
            try {
                // sends even on a broken socket
                sock.BeginSend( datamsg, 0, datamsg.Length, SocketFlags.None,
                        new AsyncCallback( SendData ), sock );
            } catch( SocketException ) {
                networkServerDown();
                return;
    }   }   }

    private void SendData( IAsyncResult iar ) {
        Socket socky = (Socket)iar.AsyncState;              // note: socky == sock
        /* int sent = */ socky.EndSend(iar);
        // do something here after send was "successful"
   }
}

----- endof csharp_tcp_client_select_alt.cs -----


# C# }}}
# Java {{{
# --------------------------------------------------------------------------------


| C/C++ | C# | Java | Perl | Python | Ruby |


# TCP
# http://gpwiki.org/index.php/Java:Tutorials:Simple_TCP_Networking
# ........................................



----- begin java_tcp_server.java -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     javac java_tcp_server.java
 *  # the file java_tcp_server.class is created
 * 
 * to run:
 *     java java_tcp_server
 *  # note, do not call: java java_tcp_server.class
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// java: TCP echo server
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.IOException;

import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;

class java_tcp_server
{
    public static void main( String argv[] ) throws Exception {
        String host = "localhost";
        int port = 50000;
        int backlog = 5;
        int maxsize = 1024;

// if host has more than one NIC/IPaddresses
//      byte [] b = new byte[] {(byte)127,(byte)0,(byte)0,(byte)1};
//      InetAddress addr = InetAddress.getByAddress(b);
        InetAddress addr = InetAddress.getByName( host );

        ServerSocket sock;
//public ServerSocket(int port) throws IOException
//public ServerSocket(int port, int backlog) throws IOException
//public ServerSocket(int port, int backlog, InetAddress bindAddr) throws IOException
        try { sock = new ServerSocket( port, backlog, addr ); }
        catch( IOException e ) {
            System.err.println( "socket error:" + e );
            return;
        }
        System.out.println( "server started on port " + port );

        while ( true ) {
            Socket client = sock.accept();          // blocking
            addr = client.getInetAddress();
            port = client.getPort();

            BufferedReader in = new BufferedReader( new InputStreamReader( client.getInputStream() ) );
//          String msg = in.readLine();             // this waits for newline...
            char[] data = new char[maxsize];
            int size = in.read( data, 0, maxsize ); // blocking & doesn't need newline to return...
            if ( size > 0 ) {
                String msg = new String( data );
                System.out.println( "connection from: " + addr + ":" + port + " " + msg );

                PrintWriter out = new PrintWriter( client.getOutputStream(), true );
                out.print( msg );                   // sends even on a broken socket
                out.flush();
                out.close();
            } else
            { System.out.println( "lost connection on recv: " + addr + ":" + port ); }
            in.close();
            client.close();
    }   }
}

----- endof java_tcp_server.java -----


# ........................................



----- begin java_tcp_client.java -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     javac java_tcp_client.java
 *  # the file java_tcp_client.class is created
 * 
 * to run:
 *     java java_tcp_client
 *  # note, do not call: java java_tcp_client.class
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// java: TCP echo client
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.IOException;

import java.net.Socket;
import java.net.SocketException;
//import java.net.UnknownHostException;

class java_tcp_client
{
    public static void main(String argv[]) throws Exception {
        String host = "localhost";
        int port = 50000;

        Socket sock;
//public Socket(String host, int port) throws UnknownHostException, IOException
//public Socket(InetAddress address, int port) throws IOException
//public Socket(String host, int port, InetAddress localAddr, int localPort) throws IOException
//public Socket(InetAddress address, int port, InetAddress localAddr, int localPort) throws IOException
        try { sock = new Socket( host, port ); }
        catch( IOException e ) {
            System.err.println( "socket error: " + e );
            return;
        }
        System.out.println( "connected to server, sending msg..." );

        PrintWriter out = new PrintWriter( sock.getOutputStream(), true );
        out.print( "Howdy" );               // sends even on a broken socket
        out.flush();
//      out.close(); // WARNING: closing here, will terminate the connection...
 
        System.out.println( "server response:" );
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader( sock.getInputStream() ) );
            String msg = in.readLine();     // blocking: server will close connection after sending msg, so can use readLine() here...
            in.close(); // note: this will also terminate the connection...
            if ( msg != null && msg.length() > 0 )
                System.out.println( "Received: " + msg );
            else
                throw new SocketException();
        } catch( SocketException e )
        { System.out.println( "lost connection on recv" ); }

//      out.close();
        sock.close();
    }
}

----- endof java_tcp_client.java -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# UDP
# ........................................



----- begin java_udp_server.java -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     javac java_udp_server.java
 *  # the file java_udp_server.class is created
 * 
 * to run:
 *     java java_udp_server
 *  # note, do not call: java java_udp_server.class
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// java: UDP echo server
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;

class java_udp_server
{
    public static void main(String args[]) throws Exception { 
        String host = "localhost";
        int port = 51000;
        int maxsize = 1024;

//public DatagramSocket(int port) throws SocketException
//public DatagramSocket(int port, InetAddress laddr) throws SocketException
        DatagramSocket sock = new DatagramSocket( port, InetAddress.getByName( host ) );
        System.out.println( "server started on port" + port );

        byte[] data = new byte[maxsize];
        while(true) {
            DatagramPacket packet = new DatagramPacket( data, data.length );
            sock.receive( packet );         // blocking
            InetAddress addr = packet.getAddress();
            port = packet.getPort();
            if ( packet.getLength() > 0 ) {
                String msg = new String( packet.getData(), 0, packet.getLength() );
                System.out.println( "msg from: " + addr + ":" + port + " " + msg );
                sock.send( packet );        // [packet] already has remote address and port set
            } else
                System.out.println( "empty msg from: " + addr + ":" + port );
    }   }
}

----- endof java_udp_server.java -----


# ........................................



----- begin java_udp_client.java -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     javac java_udp_client.java
 *  # the file java_udp_client.class is created
 * 
 * to run:
 *     java java_udp_client
 *  # note, do not call: java java_udp_client.class
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// java: UDP echo client
import java.net.DatagramSocket;
import java.net.DatagramPacket;
import java.net.InetAddress;

class java_udp_client
{
    public static void main(String args[]) throws Exception { 
        String host = "localhost";
        int port = 51000;
        
        DatagramSocket sock = new DatagramSocket();
        System.out.println( "sending msg to server..." );

        String msg = "Howdy";
        byte[] data = msg.getBytes();
        InetAddress addr =  InetAddress.getByName( host );
        DatagramPacket packet = new DatagramPacket( data, data.length, addr, port );
        sock.send( packet );

        System.out.println( "server response:" );
        sock.receive( packet );             // blocking
        sock.close();
        // note, this packet may not have come from the "server"
        addr = packet.getAddress();
        port = packet.getPort();
        if ( packet.getLength() > 0 ) {
            msg = new String( packet.getData(), 0, packet.getLength() );
            System.out.println( "msg from: " + addr + ":" + port + " " + msg );
        } else
            System.out.println( "empty msg from: " + addr + ":" + port );
    }
}

----- endof java_udp_client.java -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# SELECT
# http://www.java2s.com/Code/JavaAPI/java.nio.channels/SelectorselectedKeys.htm
# WARNING: JAVA Selector acts more like poll() when there's anything to process...
# ........................................



----- begin java_tcp_server_select.java -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     javac java_tcp_server_select.java
 *  # the file java_tcp_server_select.class is created
 * 
 * to run:
 *     java java_tcp_server_select
 *  # note, do not call: java java_tcp_server_select.class
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// java: TCP chat server with select()
// entering ANY line of input will exit the server
import java.io.IOException;

import java.net.Socket;
import java.net.InetAddress;
import java.net.InetSocketAddress;

import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

// see note about STDIN in main() below
// http://jcs.mobile-utopia.com/jcs/1928_SystemInPipe.java
//import java.nio.channels.SelectableChannel;
//import java.nio.channels.ReadableByteChannel;

import java.util.List;
import java.util.ArrayList;

class java_tcp_server_select extends Thread
{
    class Client_data
    {
        InetAddress addr;
        int port;
        SocketChannel channel;
    
        public Client_data( InetAddress a, int p, SocketChannel c ) {
            addr = a;
            port = p;
            channel = c;
        }
    }

    private Selector selector;
    private SelectionKey serverkey;
    private Boolean running;
    private List<Client_data> clients;
    private CharsetDecoder decoder;


    public static void main( String argv[] ) throws Exception {
        String host = "localhost";
        int port = 52000;

        // NOTE: "channel" and not just ServerSocket
        ServerSocketChannel server = ServerSocketChannel.open();
        InetAddress addr = InetAddress.getByName( host );
        InetSocketAddress iaddr = new InetSocketAddress( addr, port );
        server.socket().bind( iaddr );
        // WARNING: setting blocking to false means that the selector will
        // [ wake up when / trigger on ] "ANYTHING" is ready for processing.
        // i.e. it doesn't return a set of keys with "pending" data, but
        // rather all keys that has been registered.  in other words, all
        // keys needs to be polled (non-blocking) for any live (pending) data...
        server.configureBlocking( false );

        // Selector() does NOT return a list of "ready to read" objects...
        // instead, sockets (which needs to be set to non-blocking)
        // needs to be [ POLLED ] for any data.
        Selector selector = Selector.open();
        SelectionKey serverkey = server.register( selector, SelectionKey.OP_ACCEPT );
        System.out.println( "server started on port " + port );

        // STDIN: one possible way to make it a SelectableChannel
        // http://jcs.mobile-utopia.com/jcs/1928_SystemInPipe.java
//      SystemInPipe stdinPipe = new SystemInPipe();
//      SelectableChannel stdin = stdinPipe.getStdinChannel();
//      SelectionKey stdinkey = stdin.register( selector, SelectionKey.OP_READ );
//      stdinPipe.start();
        // but, trying to keep these cheatsheets runnable from the standard packages
        java_tcp_server_select networkThread = new java_tcp_server_select( selector, serverkey );
        networkThread.start();

        // think of the following as the main loop...
        System.console().readLine();        // blocking

        System.out.println( "shutting down server..." );
        // terminate any live threads -- or else program keeps running...
        networkThread.shutdown();

        // all client sockets are closed during networkThread.shutdown();
        server.close();
    }

    public java_tcp_server_select( Selector selector, SelectionKey serverkey ) {
        this.selector = selector;
        this.serverkey = serverkey;
        clients = new ArrayList<Client_data>();

        Charset charset = Charset.forName("ISO-8859-1");
        decoder = charset.newDecoder();

        running = true;
    }

    public void shutdown() {
        running = false;
        for ( Client_data client: clients )
            try { client.channel.close(); }
            catch( IOException e ) { System.out.println( "*** close socket error: " + e ); }
        clients.clear();
        interrupt();
    }

    public void run() {
        int maxsize = 1024;
        ByteBuffer data = ByteBuffer.allocate( maxsize );
        InetAddress addr;
        int port;
        String tosend;

        while( running ) {
            try { selector.select(); }      // blocking
            catch( IOException e ) { System.out.println( "*** selector select error: " + e ); }
            for ( SelectionKey key: selector.selectedKeys() ) {
                if ( key == serverkey ) {
                    // handle the server socket
                    if ( key.isAcceptable() ) {                 // POLLING...
                        ServerSocketChannel server = (ServerSocketChannel) key.channel();
                        SocketChannel client;
                        SelectionKey clientkey;
                        try {
    /* throws */            client = server.accept();           // was set to non-blocking...
                            if ( client == null )               // POLLING again...
                                continue;
    /* throws */            client.configureBlocking( false );  // !!!
    /* throws */            clientkey = client.register( selector, SelectionKey.OP_READ );
                        } catch( IOException e ) {
                            System.out.println( "*** server socket error: " + e );
                            continue;
                        }
                        addr = client.socket().getInetAddress();
                        port = client.socket().getPort();
                        Client_data c = new Client_data( addr, port, client );
                        clients.add ( c );
                        clientkey.attach( c );
                        tosend = "connection from: " + addr + ":" + port;
                        echo_and_send_to_clients( tosend );
                    }
                    continue;
                }

// if STDIN was a SelectableChannel
//              if ( key == stdinkey ) {
//                  // handle standard input
//                  ReadableByteChannel channel = (ReadableByteChannel) key.channel();
//                  int count = channel.read( data );           // PENDING data:
//                  key.cancel();
//                  channel.close();
//                  System.out.println( "shutting down server..." );
//                  running = false;        // break while loop
//                  break;                  // break for loop
//              }

                // handle all other sockets
                SocketChannel client = (SocketChannel) key.channel();
                Client_data cdata = (Client_data) key.attachment();
                if ( key.isReadable() ) {                       // POLLING...
                    int bytesread;
                    try { bytesread = client.read( data ); }    // was set to non-blocking...
                    catch( IOException e ) {
                        //System.out.println( "*** read socket error: " + e );

                        // key.isReadable() will be false the "next" time around
                        // however, pre-emptively force a close() "this" time around
                        bytesread = -1;
                    }
                    if ( bytesread > 0 ) {                      // POLLING again...
                        data.flip();
                        try {
    /* throws */            String msg = decoder.decode( data ).toString();
                            tosend = "msg from " + cdata.addr + ":" + cdata.port + " " + msg;
                            echo_and_send_to_clients( tosend );
                        } catch( IOException e ) {
                            System.out.println( "*** ByteBuffer decode error: " + e );
                        }
                        data.clear();
                    }
                    if ( bytesread >= 0 ) // 0 still means connection is still alive...
                        continue;
                }
//              key.cancel(); // this will be automatically done when channel closes...
                try { client.close(); }
                catch( IOException e ) { System.out.println( "*** close socket error: " + e ); }
                clients.remove( cdata );
                tosend = "client leaving: " + cdata.addr;
                echo_and_send_to_clients( tosend );
    }   }   }

    private void echo_and_send_to_clients( String tosend ) {
        // DO NOT CACHE ByteBuffer
//      ByteBuffer data = ByteBuffer.wrap( tosend.getBytes() );
        // java clears the ByteBuffer data after channel.write() all the time...

        System.out.println( tosend );
        for ( Client_data client: clients ) {
//          try{ client.channel.write( data ); }                // sends even on a broken socket
            try{ client.channel.write( ByteBuffer.wrap( tosend.getBytes() ) ); }
            catch( IOException e ) { System.out.println( "*** write socket error: " + e ); }
    }   }
}

----- endof java_tcp_server_select.java -----


# ........................................



----- begin java_tcp_client_select.java -----
/* written by Nick Shin - nshin@estss.com
 * created Oct 15 2010 and copyright by Nick Shin.
 * the code found in this file are licensed under the
 * Creative Commons Attribution 3.0 License
 * 
 * this file can be found at www.estss.com/opensource/cheatsheet.php
 * 
 * 
 * to compile:
 *     javac java_tcp_client_select.java
 *  # the file java_tcp_client_select.class is created
 * 
 * to run:
 *     java java_tcp_client_select
 *  # note, do not call: java java_tcp_client_select.class
 * 
 * 
 * NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
 */


// java: TCP chat client with select()
// entering ANY line of input will exit the server
// try this with more than one client...
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;

import java.net.Socket;
import java.net.InetAddress;
import java.net.InetSocketAddress;

import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.nio.channels.ClosedChannelException;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetDecoder;

class java_tcp_client_select extends Thread
{
    private Boolean running = true;
    private SocketChannel channel;
    private Selector selector;
    private ByteBuffer data;
    private CharsetDecoder decoder;

    public static void main( String argv[] ) throws Exception {
        java_tcp_client_select demo = new java_tcp_client_select();
        demo.run();
    }

    public java_tcp_client_select() {
        String host = "localhost";
        int port = 52000;
        int maxsize = 1024;

        try { // everything here throws...
            InetAddress addr = InetAddress.getByName( host );
            channel = SocketChannel.open( new InetSocketAddress( addr, port ) );
            // WARNING: see server.configureBlocking() note in class java_tcp_server_select above
            channel.configureBlocking( false );

            // NOTE: see Selector() notes in class java_tcp_server_select above
            selector = Selector.open();
            SelectionKey sockkey = channel.register( selector, SelectionKey.OP_READ );
        } catch( IOException e ) {
            System.out.println( "socket error: " + e );
            return;
        }
        System.out.println( "connected to server" );

        System.out.print( "% " );
        System.out.flush();

        // spin off threads to prevent main loop from being blocked.
//      Thread keyboardThread = new Thread( keyboardWatcher() );
//      keyboardThread.start();
        // it seems that blocking reads cannot be interrupted
        // need to do this in a round about way...
        // http://www.javaspecialists.eu/archive/Issue153.html
        BufferedReader br = new BufferedReader( new InputStreamReader( System.in ) );

        Charset charset = Charset.forName("ISO-8859-1");
        decoder = charset.newDecoder();
        data = ByteBuffer.allocate( maxsize );
        while ( running ) {
            networkWatcher();               // polls
            keyboardWatcher( br );          // polls
            try { Thread.sleep( 100 ); }    // meh...
            catch( InterruptedException e ) { }
        }

        // terminate any live threads -- or else program keeps running...
//      keyboardThread.interrupt();

        try { channel.close(); } catch( IOException e ) { }
    }

    private void networkWatcher() {
        // using a non-blocking version of the selector
        try { selector.selectNow(); } catch( IOException e ) { }

        for ( SelectionKey key: selector.selectedKeys() ) { // ITERATOR...
            SocketChannel channel = (SocketChannel) key.channel();
            // the following is not needed here, selector has been registered with only 1 channel
            //if ( key.isReadable() )
            int bytesread;
            try { bytesread = channel.read( data ); }       // was set to non-blocking...
            catch( IOException e ) {
                System.out.println( "*** read socket error: " + e );
                bytesread = 0;
            }
            if ( bytesread > 0 ) {          // POLLING...
                data.flip();
                try {
                        String msg = decoder.decode( data ).toString();
                        System.out.println( msg );
                    } catch( IOException e ) {
                        System.out.println( "*** ByteBuffer decode error: " + e );
                    }
                    System.out.print( "% " );
                    System.out.flush();
                data.clear();
            }
            if ( bytesread >= 0 ) // 0 still means connection is still alive...
                continue;
            System.out.println( "server has left the building..." );
            running = false;
    }   }

    // this is the "inlined" (during while loop above) version
    private void keyboardWatcher( BufferedReader br ) {
        try {
            if ( ! br.ready() )                 // POLLING...
                return;
        } catch( IOException e ) {
            System.out.println( "*** BufferedReader error: " + e );
            return;
        }
        String msg;
        try { msg = br.readLine(); }
        catch( IOException e ) {
            System.out.println( "*** readLine error: " + e );
            return;
        }
        msg = msg.trim();
        if ( msg.length() != 0 ) {
            try{ channel.write( ByteBuffer.wrap( msg.getBytes() ) ); }
            catch( IOException e ) { System.out.println( "*** write socket error: " + e ); }
        } else {
            System.out.println( "leaving..." );
            running = false;
    }   }

    // keeping this here for reference...
    // this is the "threaded - runnable" version
//  private Runnable keyboardWatcher() {
//      return new Runnable() {
//          public void run() {
//              while( true ) {
//                  String msg = System.console().readLine();   // blocking
//                  msg = msg.trim();
//                  if ( msg.length() != 0 ) {
//                      try{ channel.write( ByteBuffer.wrap( msg.getBytes() ) ); }
//                      catch( IOException e ) { System.out.println( "*** write socket error: " + e ); }
//                      continue;
//                  }
//                  System.out.println( "leaving..." );
//                  running = false;
//                  return;
//  }   }   };  }
}

----- endof java_tcp_client_select.java -----




# Java }}}
# Perl {{{
# --------------------------------------------------------------------------------


| C/C++ | C# | Java | Perl | Python | Ruby |


# TCP
# ........................................



----- begin perl_tcp_server.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: TCP echo server - plain ol Socket
use strict;
use Socket;

my $host = 'localhost';
my $port = 50000;
my $backlog = 5;
my $maxsize = 1024;
my $proto = getprotobyname('tcp');

socket( SOCK, PF_INET, SOCK_STREAM, $proto ) || die "socket error: $!\n";
setsockopt( SOCK, SOL_SOCKET, SO_REUSEADDR, 1 ) || die "socket option SO_REUSEADDR error: $!\n";

# if host has more than one NIC/IPaddresses
#my $addr = inet_aton( '127.0.0.1' );
#my $addr = INADDR_ANY; # a.k.a. inet_aton( '0.0.0.0' );
my $addr = gethostbyname( $host ); # note: inet_aton( $host ) also works...

my $local_addr = sockaddr_in( $port, $addr );
bind( SOCK, $local_addr ) || die "unable to bind to port $port $!\n";
listen( SOCK, $backlog ) || die "listen error: $!\n";
print "server started on port $port\n";

my $msg;
while ( my $client_addr = accept( NEW_SOCK, SOCK ) ) {  # blocking
    my ( $client_port, $client_ip ) = sockaddr_in( $client_addr );
    my $dotted_quad = inet_ntoa( $client_ip );
    my $client_host = gethostbyaddr( $client_ip, AF_INET );

    # note: perl cookbook shows the following examples, but <> will block until
    # the socket is terminated, which is too late to send a response back...
    # also, <> sometimes looks like it can be used AFTER a recv() or a send() was used first,
    # BUT, the code does not reliably continue properly -- so DO NOT READ from <>
#   if ( defined $msg = <NEW_SOCK> )
#   $msg = <NEW_SOCK>;
    my $sock = recv( NEW_SOCK, $msg, $maxsize, 0 );     # blocking: $msg will be cleared if fail recv
    if ( $msg ) {
        print "connection from: [$client_host] $dotted_quad:$client_port $msg\n";
        # DO NOT PRINT to a network handle for the same reasons ( do not read from <> ) as noted above ...
#       print NEW_SOCK $msg;                # send msg
        send( NEW_SOCK, $msg, 0 );          # sends even on a broken socket
    } else
    { print "lost connection on recv: $dotted_quad:$client_port\n"; }
    close NEW_SOCK;
}

----- endof perl_tcp_server.pl -----



----- begin perl_tcp_client.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: TCP echo client - plain ol Socket
use strict;
use Socket;

my $host = 'localhost';
my $port = 50000;
my $maxsize = 1024;
my $proto = getprotobyname('tcp');

socket( SOCK, PF_INET, SOCK_STREAM, $proto ) || die "socket error: $!\n";

my $remote_ip = gethostbyname( $host );
my $remote_addr = sockaddr_in( $port, $remote_ip );
connect( SOCK, $remote_addr ) || die "unable to connect to $remote_addr $!\n";
print "connected to server, sending msg...\n";

send( SOCK, 'Howdy', 0 );                   # sends even on a broken socket

print "server response:\n";
my $msg;
recv( SOCK, $msg, $maxsize, 0 );            # blocking: $msg will be cleared if fail recv
close SOCK;
if ( $msg )
{ print "Received: $msg\n"; }
else
{ print "lost connection on recv\n"; }

----- endof perl_tcp_client.pl -----


# ........................................



----- begin perl_tcp_server2.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: TCP echo server - using IO::Socket
use strict;
use IO::Socket;

my $host = 'localhost';
my $port = 50000;
my $backlog = 5;
my $maxsize = 1024;

my $sock = new IO::Socket::INET (
    LocalHost => $host,     # if omitted, will bind to INADDR_ANY
    LocalPort => $port,
    Proto => 'tcp',
    Listen => $backlog,
    Reuse => 1
) || die "socket error: $!\n";
print "server started on port $port\n";

my $msg;
while ( my $client_sock = $sock->accept ) { # blocking
    my $addr = $client_sock->peerhost . ':'. $client_sock->peerport;

    $client_sock->recv( $msg, $maxsize );   # blocking: $msg will be cleared if fail recv
    if ( $msg ) {
        print "connection from: $addr $msg\n";
        $client_sock->send( $msg );         # sends even on a broken socket
    } else
    { print "lost connection on recv: $addr\n"; }
    close $client_sock;
}

----- endof perl_tcp_server2.pl -----



----- begin perl_tcp_client2.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: TCP echo client - using IO::Socket
use strict;
use IO::Socket;

my $host = 'localhost';
my $port = 50000;
my $maxsize = 1024;

my $sock = new IO::Socket::INET (
    PeerAddr  => $host,
    PeerPort  => $port,
    Proto => 'tcp',
) || die "socket error: $!\n";
print "connected to server, sending msg...\n";

$sock->send( 'Howdy' );                     # sends even on a broken socket

print "server response:\n";
my $msg;
$sock->recv( $msg, $maxsize );              # blocking: $msg will be cleared if fail recv
close $sock;
if ( $msg )
{ print "Received: $msg\n"; }
else
{ print "lost connection on recv\n"; }

----- endof perl_tcp_client2.pl -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# UDP
# ........................................



----- begin perl_udp_server.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: UDP echo server - plain ol Socket
use strict;
use Socket;

my $host = 'localhost';
my $port = 51000;
my $maxsize = 1024;
my $proto = getprotobyname('udp');

socket( SOCK, PF_INET, SOCK_DGRAM, $proto ) || die "socket error: $!\n";
my $addr = gethostbyname( $host );
my $local_addr = sockaddr_in( $port, $addr );
bind( SOCK, $local_addr ) || die "unable to bind to port $port $!\n";
print "server started on port $port\n";

my $msg;
while( my $client_addr = recv( SOCK, $msg, $maxsize, 0 ) ) { # blocking
    my ( $client_port, $client_ip ) = sockaddr_in( $client_addr );
    my $dotted_quad = inet_ntoa( $client_ip );
    if ( $msg ) {
        print "msg from: $dotted_quad:$client_port $msg\n";
        send( SOCK, $msg, 0, $client_addr );    # sends even on a non-opened port
    } else
    { print "empty msg from: $dotted_quad:$client_port\n"; }
}

----- endof perl_udp_server.pl -----



----- begin perl_udp_client.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: UDP echo client -- plain ol Socket
use strict;
use Socket;

my $host = 'localhost';
my $port = 51000;
my $maxsize = 1024;
my $proto = getprotobyname('udp');

socket( SOCK, PF_INET, SOCK_DGRAM, $proto ) || die "socket error: $!\n";
print "sending msg to server...\n";

my $remote_ip = gethostbyname( $host );
my $remote_addr = sockaddr_in( $port, $remote_ip );
send( SOCK, 'Howdy', 0, $remote_addr );     # sends even on a non-opened port

print "server response:\n";
my $msg;
$remote_addr = recv( SOCK, $msg, $maxsize, 0 ); # blocking
close SOCK;
# note, this msg may not have come from the "server"
( my $remote_port, $remote_ip ) = sockaddr_in( $remote_addr );
my $dotted_quad = inet_ntoa( $remote_ip );
if ( $msg )
{ print "msg from: $dotted_quad:$remote_port $msg\n"; }
else
{ print "empty msg from: $dotted_quad:$remote_port\n"; }

----- endof perl_udp_client.pl -----


# ........................................



----- begin perl_udp_server2.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: UDP echo server - using IO::Socket
use strict;
use IO::Socket;

my $port = 51000;
my $maxsize = 1024;

my $sock = new IO::Socket::INET (
    # binding to INADDR_ANY
    LocalPort => $port,
    Proto => 'udp'
) || die "socket error: $!\n";
print "server started on port $port\n";

my $msg;
while( $sock->recv( $msg, $maxsize ) ) {    # blocking
    my $addr = $sock->peerhost . ':'. $sock->peerport;
    if ( $msg ) {
        print "msg from: $addr $msg\n";
        $sock->send( $msg );                # sends even on a non-opened port
    } else
    { print "empty msg from: $addr\n"; }
}

----- endof perl_udp_server2.pl -----



----- begin perl_udp_client2.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: UDP echo client -- using IO::Socket
use strict;
use IO::Socket;

my $host = 'localhost';
my $port = 51000;
my $maxsize = 1024;

my $sock = new IO::Socket::INET (
    PeerAddr => $host,
    PeerPort => $port,
    Proto => 'udp'
) || die "socket error: $!\n";
print "sending msg to server...\n";

$sock->send( 'Howdy' );                     # sends even on a non-opened port

print "server response:\n";
my $msg;
$sock->recv( $msg, $maxsize );              # blocking
# note, this msg may not have come from the "server"
my $addr = $sock->peerhost . ':'. $sock->peerport;
close $sock;
if ( $msg )
{ print "msg from: $addr $msg\n"; }
else
{ print "empty msg from: $addr\n"; }

----- endof perl_udp_client2.pl -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# SELECT
# http://perldoc.perl.org/IO/Select.html
# ........................................



----- begin perl_tcp_server_select.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: TCP chat server with select()
# entering ANY line of input will exit the server
use strict;
use IO::Socket;
use IO::Select;

my $host = 'localhost';
my $port = 52000;
my $backlog = 5;
my $maxsize = 1024;

my $sock = new IO::Socket::INET (
    LocalHost=> $host,
    LocalPort=> $port,
    Proto => 'tcp',
    Listen => $backlog,
    Reuse => 1
) || die "socket error: $!\n";
my $sel = new IO::Select( $sock );
print "server started on port $port\n";

$sel->add( \*STDIN );
my @ready = ();
my %clients = ();
my $msg = '';
my $tosend = '';
my $addr;
SELECT: while ( @ready = $sel->can_read ) { # blocking
    foreach my $s ( @ready ) {

        if ( $s == $sock ) { # handle the server socket
            my $client = $s->accept;        # PENDING data:
            $sel->add( $client );
            $addr = $client->peerhost . ':' . $client->peerport;
            # perl doesn't like keys anything other than text...
            $clients{ $addr } = $client;
            $tosend = 'connection from: ' . $addr;
            print $tosend . "\n";
#           foreach ( $sel->can_write )     # WARNING: STDIN is in here...
            foreach ( values %clients )
            { $_->send( $tosend ); }        # sends even on a broken socket
            next;
        }

        if ( $s == \*STDIN ) { # handle standard input
            print "shutting down server...\n";
            last SELECT;
        }

        # handle all other sockets
        $s->recv( $msg, $maxsize );         # PENDING data: $msg will be cleared if fail recv
        # if socket terminated abonormally,
        #     $s->peerhost & $s->peerport will be NULL
        #     and the following line will FAIL:
        # $addr = $s->peerhost . ':' . $s->peerport;
        # do this the long way:
        while ( my ( $key, $value ) = each %clients ) {
            next if ( $value != $s );
            $addr = $key;
            last;
        }
        if ( $msg ) {
            $tosend = "[$addr] $msg";
            print $tosend . "\n";
            foreach ( values %clients )
            { $_->send( $tosend ); }        # sends even on a broken socket
            next;
        }
        $tosend = "client leaving: $addr";
        delete $clients{ $addr };
        $sel->remove( $s );
        $s->close;
        print $tosend . "\n";
        foreach ( values %clients )
        { $_->send( $tosend ); }            # sends even on a broken socket
    }
}

foreach ( values %clients )
{ $_->close; }
$sock->close;

----- endof perl_tcp_server_select.pl -----



----- begin perl_tcp_client_select.pl -----
#!/usr/bin/perl -w

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# perl: TCP chat client with select()
# entering ANY line of input will exit the server
# try this with more than one client...
use strict;
use IO::Socket;
use IO::Select;

$|++;   # turn on auto flush

my $host = 'localhost';
my $port = 52000;
my $maxsize = 1024;

my $sock = new IO::Socket::INET (
    PeerAddr  => $host,
    PeerPort  => $port,
    Proto => 'tcp',
) || die "socket error: $!\n";
my $sel = new IO::Select( $sock );
print "connected to server...\n";

print '% ';

$sel->add( \*STDIN );
my @ready = ();
my $msg = '';
SELECT: while ( @ready = $sel->can_read ) { # blocking
    foreach my $client ( @ready ) {
        if ( $client == \*STDIN ) {
            $msg = <>;
            chomp $msg;
            if ( $msg eq '' ) {
                print "leaving....\n";
                last SELECT;
            }
            $sock->send( $msg );            # sends even on a broken socket
            next;
        }

        $client->recv( $msg, $maxsize );    # PENDING data: $msg will be cleared if fail recv
        if ( $msg ) {
            print $msg . "\n% ";
            next;
        }
        print "server has left the building...\n";
        last SELECT;
}   }
$sock->close;

----- endof perl_tcp_client_select.pl -----


# Perl }}}
# Python {{{
# --------------------------------------------------------------------------------


| C/C++ | C# | Java | Perl | Python | Ruby |


# TCP
# ........................................



----- begin python_tcp_server.py -----
#!/usr/bin/python

"""
written by Nick Shin - nshin@estss.com
created Oct 15 2010 and copyright by Nick Shin.
the code found in this file are licensed under the
Creative Commons Attribution 3.0 License

this file can be found at www.estss.com/opensource/cheatsheet.php


NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
"""


# python: TCP echo server
import socket
import sys

host, port = 'localhost', 50000
backlog = 5
maxsize = 1024

# if host has more than one NIC/IPaddresses
#addr = '127.0.0.1';
addr = host;

try:
    sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
except socket.error, msg:
    print 'socket error:', msg
    sys.exit(1)
try:
    sock.setsockopt( socket.SOL_SOCKET, socket.SO_REUSEADDR, 1 )
    sock.bind( ( addr, port ) )
    sock.listen( backlog )
except socket.error, msg:
    sock.close()
    print 'unable to bind to port :', port, ' ', msg
    sys.exit(1)
print 'server started on port ', port

while 1:
    client, address = sock.accept()         # blocking
#   client, ( addr, port ) = sock.accept()
    msg = client.recv( maxsize )            # blocking
    if msg:
        print 'connection from: ', address, ' ', msg
        client.send( msg )                  # sends even on a broken socket
    else:
        print 'lost connection on recv: ', address
    client.close() 

----- endof python_tcp_server.py -----


# ........................................



----- begin python_tcp_client.py -----
#!/usr/bin/python

"""
written by Nick Shin - nshin@estss.com
created Oct 15 2010 and copyright by Nick Shin.
the code found in this file are licensed under the
Creative Commons Attribution 3.0 License

this file can be found at www.estss.com/opensource/cheatsheet.php


NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
"""


# python: TCP echo client
import socket
import sys

host, port = 'localhost', 50000
maxsize = 1024

try:
    sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
except socket.error, msg:
    print 'socket error:', msg
    sys.exit(1)
try:
    sock.connect( ( host, port ) )
except socket.error, msg:
    sock.close()
    print 'unable to connect to ', host, ':', port, ' ', msg
print 'connected to server, sending msg...'

sock.send( 'Howdy' )                        # sends even on a broken socket

print 'server response:'
msg = sock.recv( maxsize )                  # blocking
sock.close()
if msg:
    print 'Received: ', msg
else:
    print 'lost connection on recv'

----- endof python_tcp_client.py -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# UDP
# http://www.ibm.com/developerworks/linux/tutorials/l-pysocks/section4.html
# ........................................



----- begin python_udp_server.py -----
#!/usr/bin/python

"""
written by Nick Shin - nshin@estss.com
created Oct 15 2010 and copyright by Nick Shin.
the code found in this file are licensed under the
Creative Commons Attribution 3.0 License

this file can be found at www.estss.com/opensource/cheatsheet.php


NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
"""


# python: UDP echo server
import socket
import sys

host, port = 'localhost', 51000
maxsize = 1024

try:
    sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
except socket.error, msg:
    print 'socket error:', msg
    sys.exit(1)
try:
    sock.bind( ( host, port ) )
except socket.error, msg:
    sock.close()
    print 'unable to bind to port :', port, ' ', msg
    sys.exit(1)
print 'server started on port ', port

while 1:
    msg, (addr, port) = sock.recvfrom( maxsize ) # blocking
    if msg:
        print 'msg from: ', addr, ':', port, ' ', msg
        sock.sendto( msg, (addr, port) )    # sends even on a non-opened port
    else:
        print 'empty msg from: ', addr, ':', port

----- endof python_udp_server.py -----


# ........................................



----- begin python_udp_client.py -----
#!/usr/bin/python

"""
written by Nick Shin - nshin@estss.com
created Oct 15 2010 and copyright by Nick Shin.
the code found in this file are licensed under the
Creative Commons Attribution 3.0 License

this file can be found at www.estss.com/opensource/cheatsheet.php


NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
"""


# python: UDP echo client
import socket
import sys

host, port = 'localhost', 51000
maxsize = 1024

try:
    sock = socket.socket( socket.AF_INET, socket.SOCK_DGRAM )
except socket.error, msg:
    print 'socket error:', msg
    sys.exit(1)
print 'sending msg to server...'

sock.sendto( 'Howdy', ( host, port ) )      # sends even on a non-opened port

print 'server response:'
# note, this msg may not have come from the "server"
msg, (addr, port) = sock.recvfrom( maxsize ) # blocking
sock.close()
if msg:
    print 'msg from: ', addr, ':', port, ' ', msg
else:
    print 'empty msg from: ', addr, ':', port

----- endof python_udp_client.py -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# SELECT
# http://ilab.cs.byu.edu/python/selectmodule.html
# ........................................



----- begin python_tcp_server_select.py -----
#!/usr/bin/env python

"""
written by Nick Shin - nshin@estss.com
created Oct 15 2010 and copyright by Nick Shin.
the code found in this file are licensed under the
Creative Commons Attribution 3.0 License

this file can be found at www.estss.com/opensource/cheatsheet.php


NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
"""


"""
python: TCP chat server with select()
entering ANY line of input will exit the server
"""

import select
import socket
import sys

host, port = 'localhost', 52000
backlog = 5
maxsize = 1024

try:
    sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
except socket.error, msg:
    print 'socket error:', msg
    sys.exit(1)
try:
    sock.bind( ( host, port ) )
    sock.listen( backlog )
except socket.error, msg:
    sock.close()
    print 'unable to bind to port :', port, ' ', msg
    sys.exit(1)
print 'server started on port ', port

input = [ sock, sys.stdin ]
clients = {}
running = 1
while running:
    inputready, outputready, exceptready = select.select( input, [], [] )

    for s in inputready:
    
        if s == sock:
            # handle the server socket
            client, address = sock.accept() # PENDING data:
            input.append( client )
            clients[ client ] = address
            tosend = 'connection from: ' + str( address )
            print tosend
            for c in clients:
                c.send( tosend )            # sends even on a broken socket

        elif s == sys.stdin:
            # handle standard input
            junk = sys.stdin.readline()
            print 'shutting down server...'
            running = 0                     # break while loop
            break                           # break for loop

        else:
            # handle all other sockets
            try:
                msg = s.recv( maxsize )     # PENDING data:
                # on listening socket during select(), if remote socket terminated abonormally,
                #     recv() will actually raise an exception
                #     and the following line will FAIL
                # addr = str( s.getpeername() )
            except:
                msg = 0
            addr = str( clients[ s ] )

            if msg:
                tosend = 'msg from ' + addr + ': ' + msg
                print tosend
                for c in clients:
                    c.send( tosend )        # sends even on a broken socket
            else:
                tosend = 'client leaving: ' + addr 
                input.remove( s )
                del clients[ s ]
                s.close()
                print tosend
                for c in clients:
                    c.send( tosend )        # sends even on a broken socket

for c in clients:
    c.close()
sock.close()

----- endof python_tcp_server_select.py -----


# ........................................



----- begin python_tcp_client_select.py -----
#!/usr/bin/env python

"""
written by Nick Shin - nshin@estss.com
created Oct 15 2010 and copyright by Nick Shin.
the code found in this file are licensed under the
Creative Commons Attribution 3.0 License

this file can be found at www.estss.com/opensource/cheatsheet.php


NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.
"""


"""
python: TCP chat client with select()
entering ANY line of input will exit the server
try this with more than one client...
"""

import select
import socket
import sys

host, port = 'localhost', 52000
maxsize = 1024

try:
    sock = socket.socket( socket.AF_INET, socket.SOCK_STREAM )
except socket.error, msg:
    print 'socket error:', msg
    sys.exit(1)
try:
    sock.connect( ( host, port ) )
except socket.error, msg:
    sock.close()
    print 'unable to connect to ', host, ':', port, ' ', msg
print 'connected to server...'

print '% ',
sys.stdout.flush()

input = [ sock, sys.stdin ]
running = 1
while running:
    inputready, outputready, exceptready = select.select( input, [], [] )

    for s in inputready:

        if s == sys.stdin:
            line = sys.stdin.readline().strip("\n\r")
            if line == '':
                print 'leaving....'
                running = 0                 # break while loop
                break                       # break for loop
            sock.send( line )               # sends even on a broken socket

        else:
            msg = sock.recv( maxsize )      # PENDING data:
            if msg:
                print msg
                print '% ',
                sys.stdout.flush()
            else:
                print 'server has left the building...'
                running = 0                 # break while loop
                break                       # break for loop

sock.close()

----- endof python_tcp_client_select.py -----


# Python }}}
# Ruby {{{
# --------------------------------------------------------------------------------


| C/C++ | C# | Java | Perl | Python | Ruby |


# TCP
# ........................................



----- begin ruby_tcp_server.rb -----
#!/usr/bin/ruby

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# ruby: TCP echo server
require 'socket'

host, port = 'localhost', 50000
backlog = 5
maxsize = 1024

# if host has more than one NIC/IPaddresses
#addr = '127.0.0.1';
addr = host;

sock = TCPServer::new( addr, port )
sock.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
sock.listen( backlog )
puts "server started on port #{port}"

while 1
    s = sock.accept                         # blocking
    msg = s.recv( maxsize )                 # blocking: $msg will be cleared if fail recv
    port = s.peeraddr[1]
    name = s.peeraddr[2]
    addr = s.peeraddr[3]
    if msg.length != 0
        puts "connection from: [#{name}] #{addr}:#{port} #{msg}"
        s.write( msg )                      # sends even on a broken socket
    else
        puts "lost connection on recv: [#{name}] #{addr}:#{port}"
    end
    s.close
end

----- endof ruby_tcp_server.rb -----



----- begin ruby_tcp_client.rb -----
#!/usr/bin/ruby

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# ruby: TCP echo client
require 'socket'

host, port = 'localhost', 50000
maxsize = 1024

sock = TCPSocket::new( host, port )
puts 'connected to server, sending msg...'

sock.write( 'Howdy' )                       # sends even on a broken socket

puts 'server response:'
msg = sock.recv( maxsize )                  # blocking: $msg will be cleared if fail recv
sock.close
if msg.length != 0
    puts "Received: #{msg}"
else
    puts 'lost connection on recv'
end

----- endof ruby_tcp_client.rb -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# UDP
# ........................................



----- begin ruby_udp_server.rb -----
#!/usr/bin/ruby

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# ruby: UDP echo server
require 'socket'

host, port = 'localhost', 51000
maxsize = 1024

sock = UDPSocket::new
sock.bind( host, port )
puts "server started on port #{port}"

while 1
    msg, from = sock.recvfrom( maxsize )    # blocking: $msg will be cleared if fail recv
    port = from[1]
    name = from[2]
    addr = from[3]
    if msg.length != 0
        puts "msg from: [#{name}] #{addr}:#{port} #{msg}"
        sock.send( msg, 0, name, port )     # sends even on a non-opened port
    else
        puts "empty msg from: [#{name}] #{addr}:#{port}"
    end
end

----- endof ruby_udp_server.rb -----



----- begin ruby_udp_client.rb -----
#!/usr/bin/ruby

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# ruby: UDP echo client
require 'socket'

host, port = 'localhost', 51000
maxsize = 1024

sock = UDPSocket::new
sock.connect( host, port )
puts 'sending msg to server...'

sock.send( 'Howdy', 0 )                     # sends even on a non-opened port

puts 'server response:'
msg, from = sock.recvfrom( maxsize, 0 )     # blocking: $msg will be cleared if fail recv
sock.close
# note, this msg may not have come from the "server"
port = from[1]
name = from[2]
addr = from[3]
if msg.length != 0
    puts "msg from: [#{name}] #{addr}:#{port} #{msg}"
else
    puts 'empty msg from: [#{name}] #{addr}:#{port}'
end

----- endof ruby_udp_client.rb -----


| C/C++ | C# | Java | Perl | Python | Ruby |

# SELECT
# ........................................



----- begin ruby_tcp_server_select.rb -----
#!/usr/bin/ruby

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# ruby: TCP chat server with select()
# entering ANY line of input will exit the server
require 'socket'

host, port = 'localhost', 52000
backlog = 5
maxsize = 1024

sock = TCPServer::new( host, port )
sock.setsockopt( Socket::SOL_SOCKET, Socket::SO_REUSEADDR, 1 )
sock.listen( backlog )
puts "server started on port #{port}"

input = [ sock, STDIN ]
clients = {}
running = true
while running
    result = select( input, nil, nil )
    for s in result[0]
        if s == sock
            # handle the server socket
            client = sock.accept                        # PENDING data:
            port = client.peeraddr[1]
            name = client.peeraddr[2]
            addr = client.peeraddr[3]
            input.insert( -1, client )
            clients[ client ] = "#{addr}:#{port}";
            tosend = "connection from: #{addr}:#{port}"
            puts tosend
            clients.each { |c,v| c.write( tosend ) }    # sends even on a broken socket

        elsif s == STDIN
            # handle standard input
            junk = STDIN.gets
            puts 'shutting down server...'
            running = false                             # break while loop
            break                                       # break for loop

        else 
            # handle all other sockets
            begin
                msg = s.recv( maxsize )                 # PENDING data:
                # on listening socket during select(), if socket terminated abonormally,
                #     recv() will actually raise an exception
                # also, s.addr[1] thru s.addr[3] will be set to NULL
                #     and the following will FAIL
                # addr = "#{s.addr[3]}:#{s.addr[1]}"
            rescue
                msg = ""
            end
            addr = clients[s]
            if msg.length != 0
                tosend = "msg from #{addr} #{msg}"
                puts tosend
                clients.each { |c,v| c.write( tosend ) }    # sends even on a broken socket
            else
                tosend = "client leaving: #{addr}"
                input.delete( s )
                clients.delete( s )
                s.close
                puts tosend
                clients.each { |c,v| c.write( tosend ) }    # sends even on a broken socket
            end
        end
    end
end
clients.each { |c,v| c.close }
sock.close

----- endof ruby_tcp_server_select.rb -----



----- begin ruby_tcp_client_select.rb -----
#!/usr/bin/ruby

# written by Nick Shin - nshin@estss.com
# created Oct 15 2010 and copyright by Nick Shin.
# the code found in this file are licensed under the
# Creative Commons Attribution 3.0 License
# 
# this file can be found at www.estss.com/opensource/cheatsheet.php
# 
# 
# NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.


# ruby: TCP chat client with select()
# entering ANY line of input will exit the server
# try this with more than one client...
require 'socket'

STDOUT.sync = true  # turn on auto flush

host, port = 'localhost', 52000
maxsize = 1024

sock = TCPSocket::new( host, port )
puts 'connected to server...'

print '% '

input = [ sock, STDIN ]
running = true
while running
    result = select( input, nil, nil )
    for s in result[0]
        if s == STDIN
            line = STDIN.gets.chomp
            if line == ''
                puts 'leaving...'
                running = false             # break while loop
                break                       # break for loop
            end
            sock.write( line )              # sends even on a broken socket

        else 
            msg = sock.recv( maxsize )      # PENDING data:
            if msg.length != 0
                puts msg
                print '% '
            else
                puts 'server has left the building...'
                running = false             # break while loop
                break                       # break for loop
            end
        end
    end
end
sock.close

----- endof ruby_tcp_client_select.rb -----


# Ruby }}}
# --------------------------------------------------------------------------------


| C/C++ | C# | Java | Perl | Python | Ruby |