JAVA TCP Echo Server/Client Example Code

基本上我不喜歡 JAVA。倒不是說物件導向(Object-Oriented)的觀念不好,而是我不喜歡一些簡單的事情也要要用物件導向的觀念來寫(單單一個 Hello World 也要寫個 Class ...)。當然有人會說 C++ 不也是這樣,以 Hello World 來說,你也要先 include iostream 這個 Class,但起碼它看起來比較像 C,而且開發者不用特地去包一層物件。

抱怨完畢,現在要列在這裡的是 TCP 的 Server 和  Client 的範例程式,範例來源一樣是http://www.cs.uic.edu/~troy/spring05/cs450/sockets/socket.html

在這個範例裡面,要特別注意的是 thread 的用法。在呼叫 start() 的時候,程式會去執行 run() 的函式,下面是 javadoc 的說明。


public void start()

Causes this thread to begin execution; the Java Virtual Machine calls the run method of this thread.
The result is that two threads are running concurrently: the current thread (which returns from the call to the start method) and the other thread (which executes its run method).


TCP Server

import java.net.*; 
import java.io.*; 

class TCPEchoServer extends Thread
{
    protected static boolean serverContinue = true;
    protected Socket clientSocket;
    

    public static void main(String[] args) throws IOException 
    { 
        ServerSocket serverSocket = null;
        int serverPort = 9876;

        try 
        { 
            if ( args.length > 0 )
            {
                serverPort = new Integer( args[0] ).intValue();
            }
            
            serverSocket = new ServerSocket(serverPort); 
            System.out.println ("Connection Socket Created");
         
            try 
            { 
                while (serverContinue)
                {
                    serverSocket.setSoTimeout(10000);
                    System.out.println ("Waiting for Connection");
                    
                    try 
                    {
                        new TCPEchoServer (serverSocket.accept()); 
                    }
                    catch (SocketTimeoutException ste)
                    {
                        System.out.println ("Timeout Occurred");
                    }
                }
            } 
            catch (IOException e) 
            { 
                System.err.println("Accept failed."); 
                System.exit(1); 
            } 
        } 
        catch (IOException e) 
        { 
            System.err.println("Could not listen on port: " + serverPort ); 
            System.exit(1); 
        } 
        finally
        {
            try 
            {
                System.out.println ("Closing Server Connection Socket");
                serverSocket.close(); 
            }
            catch (IOException e)
            { 
                System.err.println("Could not close port: " + serverPort); 
                System.exit(1); 
            } 
        }
    }

    private TCPEchoServer (Socket clientSoc)
    {
        clientSocket = clientSoc;
        start();
    }

    public void run()
    {
        System.out.println ("New Communication Thread Started");

        try 
        { 
            PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true); 
            BufferedReader in = new BufferedReader( new InputStreamReader( clientSocket.getInputStream())); 

            String inputLine; 

            while ((inputLine = in.readLine()) != null) 
            { 
                System.out.println ("Server: " + inputLine); 

                if (inputLine.equals("?")) 
                {
                    inputLine = new String ("\"Bye.\" ends Client, " + "\"End Server.\" ends Server");
                }
                
                out.println(inputLine); 

                if (inputLine.equals("Bye."))
                { 
                        break;
                }                
                if (inputLine.equals("End Server.")) 
                {  
                    serverContinue = false;
                    break;
                } 
            } 

            out.close(); 
            in.close(); 
            clientSocket.close(); 
        } 
        catch (IOException e) 
        { 
            System.err.println("Problem with Communication Server");
            System.exit(1); 
        } 
    }
}


TCP Client

import java.io.*;
import java.net.*;

class TCPEchoClient 
{
    public static void main(String[] args) throws IOException 
    {
        String serverHostname = new String ("127.0.0.1");
        int serverPort = 9876;

        if (args.length > 0)
        {
           serverHostname = args[0];
        }
        
        if ( args.length > 1 )
        {
            serverPort = new Integer( args[1] ).intValue();
        }
        
        System.out.println ("Attemping to connect to host " + serverHostname + " on port "+ serverPort );

        Socket echoSocket = null;
        PrintWriter out = null;
        BufferedReader in = null;

        try 
        {
            echoSocket = new Socket(serverHostname, serverPort);
            out = new PrintWriter(echoSocket.getOutputStream(), true);
            in = new BufferedReader(new InputStreamReader(echoSocket.getInputStream()));
        } 
        catch (UnknownHostException e) 
        {
            System.err.println("Don't know about host: " + serverHostname);
            System.exit(1);
        } 
        catch (IOException e) 
        {
            System.err.println("Couldn't get I/O for " + "the connection to: " + serverHostname);
            System.exit(1);
        }

        BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in));
        String userInput;

        System.out.println ("Type Message (\"Bye.\" to quit)");
        
        while ((userInput = stdIn.readLine()) != null) 
        {
            out.println(userInput);

            // end loop
            if (userInput.equals("Bye.") || userInput.equals("End Server."))
            {
                break;
            }
            System.out.println("echo: " + in.readLine());
        }

        out.close();
        in.close();
        stdIn.close();
        echoSocket.close();
    }
}


留言

這個網誌中的熱門文章

我弟家的新居感恩禮拜分享:善頌善禱

Openssl 範例程式:建立SSL連線

如何利用 Wireshark 來監聽 IEEE 802.11 的管理封包