Java 的網路程式(Network programming)也很簡單

範例參考: 
 http://www.csie.nctu.edu.tw/~tsaiwn/oop/java/03_sample_JavaPrograms/
   子目錄: 21_network/
 也請參考之前說過的 Thread programming

Java 把網路程式設計相關 functions 包裝成很容易使用的物件類別,
  相關 class 都在 java.net.*  (所以要 import java.net.*; )

(1) TCP (Transmission Control Protocol) 網路程式設計
  (1a) TCP Server
    (a) new 一個 ServerScoket(port), 假設叫做 s
         參數 port 是一個整數, 表示要 "聽" 該 TCP port
     也就是若 封包中指定採用 TCP, 且其 port 值(2 bytes)符合就交給此程式
     注意 new ServerSocket 可能會產生 Exception, 要處理
    (b) Socket cs = s.accept( );
      這會卡住, 等有 TCP Client 連進來才會繼續, 會得到一個 Socket 物件 cs
      因為可能會有很多 Client 連進來, 通常我們立刻把這 cs 傳給一個Thread 處理,
      然後繼續等下一個 Client 連進來, 所以通常把這句寫在 Loop 內
    (c) 有了 Socket cs, 就可用 Socket 這 class 內許多 functions
       一般是先從 Socket 拉出輸入與輸出串流(水管:-)
       InputStream is = cs.getInputStream( );   // 相當於鍵盤
       outputStream os = cs.getOutputStream( );  // 相當於螢幕
       另外 cs.getPort( ) 可以取得對方目前使用那個 port 與我方溝通
    (d) 把 is 包裝成 BufferedReader 就可使用 readLine( ) 讀取對方送來訊息
        把 os 包裝成 PrintStream 就可使用 println 與 print 甚至 printf 送出訊息
    (e) 使用 InetAddress who = cs.getInetAddress( ); 取得對方 InetAddress
        再使用 InetAddress 這 class 的 functions 可取得對方許多資訊, 例如:
        String name = who.getHostName( );

  (1b) TCP Client
    (a) new 一個 Socket 例如 Socket cs = new Socket(host, port);
        其中 host 是 InetAddress, 為對方(Server)的 InetAddress
        可以這像樣取得 host = InetAddress.getByName( "www.nctu.edu.tw" );
        port 則是對方(Server) 提供 Service 的 port number (整數 2 bytes)
    (b) 然後這個 Socket cs 用起來與上述TCP Server 的 Socket cs 一樣!
 ==========================================
(2) UDP (User Datagram Protocol) 網路程式設計
  (2a) UDP Server (Receiver 接收者)
    (a) new 一個DatagramSocket 備用(牆上挖一個洞備用), 例如: 
        DatagramSocket skt = new DatagramSocket(port);  // port 是整數
        這表示我們在聽 UDP port 之 port number 為 port
    (b)準備好一個籃子, 空的 DatagramSocket, 注意會用到 byte array
        byte[] buffer = new byte[1600];
        DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
    (c)把藍子packet擺在 (a)挖的洞口:
        skt.receive(packet);  // Wait to receive a Datagram
          這會卡住直到有封包送過來!
    (d)處理(c)收到的封包, 例如把 byte array 轉成字串:
        String s = new String(buffer, 0, packet.getLength());
       另外, packet.getPort( ); 可取得對方的 port
       packet.getAddress() 可以取得對方的 InetAddress, 然後可
        用 InetAddress 的 getHostName( ) 取得對方的 HostName
    ** 因為通常會很多封包送過來, 所以通常 (c),(d)寫在 Loop 內

  (2b) UDP Clinet (Sender 送訊者) 類似去郵局寄包裹!
    (a) new 一個DatagramSocket 備用(牆上挖一個洞備用), 例如:
        DatagramSocket skt = new DatagramSocket();  // 注意與(2a)不同
    (b)準備好要送出的封包DatagramPacket packet
       (b1)訊息通常是 String, 先轉成 Byte array
           String msg = "Hello how are you 你好嗎???";
           byte[] msgbb = new byte[2*msg.length()];
           msgbb = msg.getBytes( );
       (b2)把 byte array 包成DatagramPacket封包:
       DatagramPacket packet=
           new DatagramPacket(msgbb, msgbb.length, address, port);
       此處 address 是對方的 InetAddress,  port 是對方的 port
    (c) 透過(a)挖的洞(DatagramSocket)把封包送出, 例如:
        skt.send(packet);
  UDP is Unreliable: 無法知道有沒有成功送達