在 Oracle 網站上,有個簡單的 UDP 程式範例 --- Lesson: All About Datagrams,這個程式和前一個程式基本上是差不多的,差別在於,它是由 client 先送個 request 給 server 端,server 端接收到後,回應訊息給 client 端,下面是 Oracle 的範例程式。
1 package idv.steven; 2 3 import java.io.*; 4 import java.net.*; 5 import java.util.*; 6 7 public class QuoteClient { 8 public static void main(String[] args) throws IOException { 9 10 if (args.length != 1) { 11 System.out.println("Usage: java QuoteClient <hostname>"); 12 return; 13 } 14 15 //get a datagram socket 16 DatagramSocket socket = new DatagramSocket(); 17 18 //send request 19 byte[] buf = new byte[256]; 20 InetAddress address = InetAddress.getByName(args[0]); 21 DatagramPacket packet = new DatagramPacket(buf, buf.length, address, 4445); 22 socket.send(packet); 23 24 //get response 25 packet = new DatagramPacket(buf, buf.length); 26 socket.receive(packet); 27 28 //display response 29 String received = new String(packet.getData(), 0, packet.getLength()); 30 System.out.println("Quote of the Moment: " + received); 31 32 socket.close(); 33 } 34 }
client 端程式在送出 request 後,會停在第 26 行,以等待 server 端的 response。
1 package idv.steven; 2 3 import java.io.IOException; 4 5 public class QuoteServer { 6 7 public static void main(String[] args) throws IOException { 8 new QuoteServerThread().start(); 9 } 10 }
1 package idv.steven; 2 3 import java.io.*; 4 import java.net.*; 5 import java.util.*; 6 7 public class QuoteServerThread extends Thread { 8 9 protected DatagramSocket socket = null; 10 protected BufferedReader in = null; 11 protected boolean moreQuotes = true; 12 13 public QuoteServerThread() throws IOException { 14 this("QuoteServerThread"); 15 } 16 17 public QuoteServerThread(String name) throws IOException { 18 super(name); 19 socket = new DatagramSocket(4445); 20 21 try { 22 in = new BufferedReader(new FileReader("one-liners.txt")); 23 } catch (FileNotFoundException e) { 24 System.err.println("Could not open quote file. Serving time instead."); 25 } 26 } 27 28 public void run() { 29 30 while (moreQuotes) { 31 try { 32 byte[] buf = new byte[256]; 33 34 // receive request 35 DatagramPacket packet = new DatagramPacket(buf, buf.length); 36 socket.receive(packet); 37 38 // figure out response 39 String dString = null; 40 if (in == null) 41 dString = new Date().toString(); 42 else 43 dString = getNextQuote(); 44 45 buf = dString.getBytes(); 46 47 // send the response to the client at "address" and "port" 48 InetAddress address = packet.getAddress(); 49 int port = packet.getPort(); 50 packet = new DatagramPacket(buf, buf.length, address, port); 51 socket.send(packet); 52 } catch (IOException e) { 53 e.printStackTrace(); 54 moreQuotes = false; 55 } 56 } 57 socket.close(); 58 } 59 60 protected String getNextQuote() { 61 String returnValue = null; 62 try { 63 if ((returnValue = in.readLine()) == null) { 64 in.close(); 65 moreQuotes = false; 66 returnValue = "No more quotes. Goodbye."; 67 } 68 } catch (IOException e) { 69 returnValue = "IOException occurred in server."; 70 } 71 return returnValue; 72 } 73 }
server 端程式啟動後,會先停在第 36 行以等待 request,當收到 request 後程式立即往下執行,server 端的回應內容只是由文字檔 one-liners.txt 中抓取一行文字將它回傳給 client 端。至於 client 端在那? 從程式第 48、49 行可以看到,由 client 端傳來的封包中,可以解析出 client 端的網址和 port 號,因此,server 端知道要將回應值傳向那裡。
沒有留言:
張貼留言