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: 無法知道有沒有成功送達