java 網路程式設計 第 8 章 用 java 實作 以 udp 協定為主的應用. 認識 udp 協定...
TRANSCRIPT
![Page 1: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/1.jpg)
Java 網路程式設計
第 8 章 用 Java 實作以 UDP 協定為主的應用
![Page 2: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/2.jpg)
認識 UDP 協定
UDP(user datagram protocol) 協定可以讓應用程式在不需要建立連線(connection) 的情況下送出封裝的 IP 封包 (encapsulated IP datagrams)
有關於 UDP 的資訊可以查詢 RFC 768的文件
UDP 傳送的片段 (segments) 包括 8 個bytes 的 header 與隨後的 payload
![Page 3: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/3.jpg)
UDP header 的格式
![Page 4: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/4.jpg)
通訊埠 (port) 的分配與使用
![Page 5: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/5.jpg)
以 UDP 為基礎的幾個網際網路協定
BootP(Boot Protocol) DHCP(dynamic host configuration
protocol)SNMP(simple network management
protocol)TFTP(trivial file transfer protocol)DNS(domain name system)
![Page 6: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/6.jpg)
在 IP 封包中和協定有關的資料
![Page 7: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/7.jpg)
各種網際網路協定使用的 port number
協定 Port
number
Transport協定
涵義
BootP 67 U DP BOOTstrap協定(server)
BootP 68 U DP BOOTstrap協定(client)
DH C P 67 U DP DH C P 協定(server)
DH C P 68 U DP DH C P 協定(client)
DN S 53 U DP/TC P Domain name system
FTP 21 TC P Server/control
FTP 20 TC P Server/data
H TTP 80 TC P/U DP H TTP/server
N etBT 138 U DP N etBIOS datagram
N etBT 139 TC P N etBIOS session
SM TP 25 TC P SM TP/server
SN M P 161 U DP SN M P/server
SN M P 162 U DP SN M P/trap manager
Telnet 23 TC P 遠端登入
TFTP 69 U DP 簡易(trivial)FTP
WIN S 137 U DP Windows Internet N ame Service
![Page 8: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/8.jpg)
IP 協定的 protocol type value
協定 10進位 16進位 說明
EGP 8 8 Exterior Gateway Protocol
IC M P 1 1 Internet C ontrol M essage Protocol
IGM P 2 2 Internet G roup M anagement Protocol
IGRP 88 58 Internet Gateway Routing Protocol
OSPF 89 59 Open Shortest Path First
TC P 6 6 Transmission C ontrol Protocol
U DP 17 11 U ser Datagram Protocol
![Page 9: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/9.jpg)
Client 的定義與觀點
The client-server paradigm uses the direction of initiation to categorize whether a
program is a client or server. In general, an application that initiates peer-to-peer
communication is called a client. End users usually invoke client software when
they use a network service.
![Page 10: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/10.jpg)
Server 的定義與觀點
Each time a client application executes, it contacts a server, sends a request, and
awaits a response. A server is any program that waits for incoming communication
requests from a client. The server receives a client’s request, performs the
necessary computation, and returns the result to the client.
![Page 11: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/11.jpg)
通訊軟體設計的觀點
多重協定的伺服程式 (multiprotocol servers)
多重服務的伺服程式 (multiservice servers)
![Page 12: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/12.jpg)
multiprotocol server 的架構
![Page 13: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/13.jpg)
connection-oriented multiservice server 的架構
![Page 14: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/14.jpg)
concurrent, connection-oriented multiservice server 的架構
![Page 15: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/15.jpg)
Java 對於 UDP 的支援
java.net.DatagramPacket 類別java.net.DatagramSocket 類別
![Page 16: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/16.jpg)
建立在 UDP 上的應用實作
用 UDP 實作 Echo Protocol 另外一種 Echo Service 的設計實作 DNS
![Page 17: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/17.jpg)
RFC 文件
縮寫 協定名稱 RFC 文件號碼
ARP Address resolution 826
DH C P Dynamic host configuration 1541
DN S Domain name system 1034, 1035
FTP File transfer 959
IC M P Internet control message 792
IP Internet 791
N BT N etBIOS over TC P 1001,1002
TC P Transmission control protocol 793
Telnet Teletype network service 854
U DP U ser datagram protocol 768
![Page 18: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/18.jpg)
UDP Server 程式 // UDP Server 程式 import java.io.*; import java.net.*; public class Server { public static void main(String args[]) throws Exception { byte buffer[]=new byte[10]; String msg; int portNo=5555; System.out.println("Server 端開始接受連線請求 !"); for (;;) { DatagramPacket packet = new DatagramPacket(buffer,buffer.length); DatagramSocket socket=new DatagramSocket(portNo); socket.receive(packet); msg=new String(buffer,0,packet.getLength()); System.out.println(" 收到下面的訊息 : " + msg); socket.close(); } } }
![Page 19: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/19.jpg)
UDP 客戶端的程式 // UDP 客戶端的程式 import java.io.*; import java.net.*; public class Client { public static void main(String args[]) throws Exception { int portNo =5555; System.out.print("Please input the IP address of destination :"); BufferedReader uip= new BufferedReader(new InputStreamReader(System.in)); String ServerIP=uip.readLine(); InetAddress addr=InetAddress.getByName(ServerIP); while (true) { System.out.print("輸入送出的訊息 :"); String msg=uip.readLine(); int oLength=msg.length(); byte buffer[]=new byte[oLength]; buffer=msg.getBytes(); DatagramPacket packet= new DatagramPacket(buffer,oLength,addr,portNo); DatagramSocket socket=new DatagramSocket(); socket.send(packet); socket.close(); } } }
![Page 20: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/20.jpg)
EchoUDPServer .java import java.net.*; import java.io.*; public class EchoUDPServer extends Thread { public static int SPORT = 7; // standard UDP port=7 public static int checkTime = 5000; // 預設的termination check time (以milliseconds為單位) // 最大的UDP資料長度 , 單位為bytes public static int maxUDP = 65508; // maximum UDP data length protected DatagramSocket socket; protected boolean onForService; public EchoUDPServer(int port) throws SocketException { super("EchoServer(" + port + ")"); socket = new DatagramSocket(port); socket.setSoTimeout(checkTime); onForService = true; start(); } public void ending() { onForService = false; } public void run() { System.out.println("Echo server使用以下的port : " + socket.getLocalPort()); DatagramPacket inputPacket = new DatagramPacket(new byte[maxUDP],maxUDP); while(onForService) { try { inputPacket.setLength(maxUDP); socket.receive(inputPacket); System.out.println("Echo server有收到資料! "); /* System.out.println("Echo server收到的資料 : "+ new String(inputPacket.getData())); */ socket.send(inputPacket); // 收到的資料再轉送出去(echo) } catch (InterruptedIOException e) { } catch (Throwable e) { } } try { socket.close(); } catch (Throwable e) { } } public static void main(String[] args) { if (args.length > 1) { System.err.println("使用方式 : EchoUDPServer { <port> }"); System.exit(1); } int port = SPORT; if (args.length == 1) { try { port = Integer.parseInt(args[0]); } catch (NumberFormatException e) { System.err.println("無效的port number : " + args[0]); System.exit(1); } } try { EchoUDPServer server = new EchoUDPServer(port); server.join(); } catch (Throwable e) { System.err.println("EchoUDPServer: " + e); System.exit(1); } } }
![Page 21: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/21.jpg)
EchoUDPClient.java import java.net.*; import java.io.*; public class EchoUDPClient { // 依據RFC 862 , UDP echo service的標準使用port number =7 public static final int SPORT = 7; // 嘗試接收echo server回應的次數 public static final int try_times = 3; // 嘗試的次數 public static final int etime = 1500; // 判定過時的期限, 以milliseconds為單位 // Maximum UDP payload size public static final int bsize = 508; // UDP buffer上限 // 為了產生單一echo請求的計數器 protected static int nextRequestID= 1250; // 避免instantiation private EchoUDPClient() { } // 假如主機有在指定的port上執行UDP echo service, 而且能傳回測試 // 的訊息, 則return true // 每隔一段時間做幾次的檢查 // ____________________________________________________________________ echo method public static boolean echo(InetAddress address,int port,int tries, int eheckExpire) throws IOException, SecurityException { if (address == null) throw new NullPointerException("echo server address的參數為空值"); // 產生唯一的request ID long outputReqID; synchronized(EchoUDPClient.class) { outputReqID = nextRequestID; System.out.println("outputReqID= "+outputReqID); nextRequestID++; } // 產生request packet payload (把資料寫入byte array) ByteArrayOutputStream OutputInByte = new ByteArrayOutputStream(); DataOutputStream Outputdata = new DataOutputStream(OutputInByte); try { Outputdata.writeLong(outputReqID); // 注意outputReqID是怎麼來的 Outputdata.close(); } catch (IOException e) { throw new RuntimeException("未預期的I/O例外狀況 : " + e); } // 由request來建立datagram packet DatagramPacket outputPacket = new DatagramPacket(OutputInByte.toByteArray(), OutputInByte.size(), address, port); DatagramPacket inputPacket = new DatagramPacket (new byte[bsize], bsize); DatagramSocket socket = new DatagramSocket(); socket.setSoTimeout(eheckExpire); try { for(int i=0; i<tries; i++) { /* System.out.println("Echo client送出的資料 : "+ new String(outputPacket.getData())); */ // 注意資料的處理 socket.send(outputPacket); try { socket.receive(inputPacket); // 等待接收資料 } catch (InterruptedIOException e) { continue; // 再嘗試 } catch (IOException e) { continue; } /* System.out.println("Echo client收到的資料 : "+inputPacket.getData()); */ // 將收到得byte-array轉成Java Unicode string ByteArrayInputStream byteArrayIn = new ByteArrayInputStream(inputPacket.getData(), 0, inputPacket.getLength()); DataInputStream dataInput = new DataInputStream(byteArrayIn); try { long reqID = dataInput.readLong(); System.out.println("client received : "+reqID); // client收到的 server echo if (outputReqID == reqID) { return(true); } } catch (IOException e) { } inputPacket.setLength(bsize); } } finally { try { socket.close(); } catch (Throwable e) { } } return(false); } // 主程式進入點___________________________________________ public static void main(String[] args) { if ( (args.length == 0) || (args.length > 2) ) { System.err.println("使用方式 : EchoUDPClient <host> {<port>}"); System.exit(1); } InetAddress address = null; try { address = InetAddress.getByName(args[0]); System.out.println("From client : "+address); } catch (UnknownHostException e) { System.err.println("無法找到主機 : " + args[0]); System.exit(1); } int port = SPORT; if (args.length > 1) { try { port = Integer.parseInt(args[1]); } catch (NumberFormatException e) { System.err.println("port number無效 " + args[1]); System.exit(1); } } try { if (echo(address, port, try_times , etime)) { System.out.println("以下的位址有提供echo service : " + address); } else { System.out.println("以下的位址未能echo : " + address); } System.exit(0); } catch (Throwable e) { System.err.println("EchoUDPClient: " + e); System.exit(1); } } // main方法結束 }
![Page 22: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/22.jpg)
MultiEcho.java import java.net.*; import java.io.*; class SimpleEchoServer extends Thread { private DatagramSocket ssock = null; SimpleEchoServer(int port) { try { ssock = new DatagramSocket(port); } catch (SocketException e) { e.printStackTrace(); } } public void run() { if (ssock == null) return; byte[] inbuf = new byte[24]; DatagramPacket request = new DatagramPacket(inbuf, inbuf.length); try { while (true) { // 準備等待連線接收資料 System.out.println("(server) Using port number " + ssock.getLocalPort()); System.out.println("(server) Using address " + ssock.getLocalAddress()); ssock.receive(request); System.out.println("server收到的資料 : "+ new String(request.getData())); // 傳回送出的資料 System.out.println("server送出去的資料 : "+ new String(request.getData())); ssock.send(request); } } catch (IOException e) { e.printStackTrace(); } } } class MultiEcho { static int echo_port = 7; // echo method在此____________________________________ (這是client端的動作) public static void echo(String msg, InetAddress dst, int port) { byte[] inbuf = new byte[24]; byte[] outbuf = msg.getBytes(); try { // DatagramSocket csock = new DatagramSocket(7); // 試試看有何結果! DatagramSocket csock = new DatagramSocket(); DatagramPacket request = new DatagramPacket(outbuf, outbuf.length, dst, port); DatagramPacket reply = new DatagramPacket(inbuf, inbuf.length); csock.send(request); System.out.println("client送出去的資料 : "+ new String(request.getData())); // 注意資料的處理方式 csock.receive(reply); System.out.println("client port number " + csock.getLocalPort()); System.out.println("client host address " + csock.getLocalAddress()); csock.close(); System.out.println("client收到的資料 : "+ new String(reply.getData())); } catch (SocketException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } // 主程式進入點 __________________________________________ public static void main(String[] args) { if (args.length != 1) { System.err.println("使用方式 : java MultiEcho <message>"); System.exit(1); } // 啟動echo server SimpleEchoServer srv = new SimpleEchoServer(echo_port); // 呼叫建構子 // srv.setDaemon(true); // 設定成background daemon process srv.start(); try { // 這一段可以產生一個echo client // InetAddress dst = InetAddress.getLocalHost(); // 可以試試! InetAddress dst = InetAddress.getByName("localhost"); System.out.println(dst); echo(args[0], dst, echo_port); // 呼叫echo } catch (UnknownHostException e) { System.err.println("主機不明 : " + e); } } }
![Page 23: Java 網路程式設計 第 8 章 用 Java 實作 以 UDP 協定為主的應用. 認識 UDP 協定 UDP(user datagram protocol) 協定可以讓 應用程式在不需要建立連線](https://reader036.vdocuments.pub/reader036/viewer/2022081421/56649f555503460f94c78b26/html5/thumbnails/23.jpg)
UDPClient.java import java.io.*; import java.net.*; // 本類別建立一個UDP datagram client的基本架構 public class UDPClient { public final static boolean Debug = true; public final static int MAX_DGRAM_SIZE = 512, //收到的datagram的上限 NUM_RETRIES = 3; //重送的次數 protected DatagramSocket sock; // 用來接收與傳送資料 protected DatagramPacket outPacket, inPacket; protected byte[] outBuffer, inBuffer; protected int outBufferLen, inBufferLen; protected int outPort, inPort; protected InetAddress remoteAddress; protected int RTimer = 2400, //以milliseconds為單位 retry = 0; //重試的次數 protected DatagramReplyT replySlave; protected DatagramSendT sendSlave; // 建構子 // inBufSize: 收到的data buffer的大小 // outBuf: 傳送的資料 public UDPClient(int inBufSize,byte[] outBuf, int localPort, int remotePort, InetAddress remoteAddress, int waiting ) { outPort = remotePort; inPort = localPort; outBuffer = outBuf; outBufferLen = outBuf.length; inBufferLen = ((inBufSize > 0) ? inBufSize: MAX_DGRAM_SIZE); inBuffer = new byte[inBufferLen]; remoteAddress = remoteAddress; RTimer = ((waiting > 0) ? waiting: RTimer); inPacket = new DatagramPacket(inBuffer, inBufferLen); outPacket = new DatagramPacket(outBuffer, outBufferLen, remoteAddress, outPort); } // output buffer未定時使用的建構子 public UDPClient(int inBufSize,int localPort, int remotePort, InetAddress remoteAddress,int waiting ) { outPort = remotePort; inPort = localPort; inBufferLen = ((inBufSize > 0) ? inBufSize: MAX_DGRAM_SIZE); inBuffer = new byte[inBufferLen]; remoteAddress = remoteAddress; RTimer = ((waiting > 0) ? waiting: RTimer); inPacket = new DatagramPacket(inBuffer, inBufferLen); } public void setOutputBuf(byte[] outBuf) { outBuffer = outBuf; outBufferLen = outBuf.length; outPacket = new DatagramPacket(outBuffer, outBufferLen, remoteAddress, outPort); } public DatagramPacket procTrans() throws SocketException, IOException { retry = 0; Bind(); sendSlave = new DatagramSendT(outPacket, sock,RTimer); replySlave = new DatagramReplyT(inPacket, sock,NUM_RETRIES * RTimer); sendSlave.start();// 開始傳送datagrams replySlave.start();//開始等待接收datagrams int receivingState = replySlave.waitOnReply();//在此阻絕 if (Debug) System.out.println("UDPClient receivingState: " + receivingState); if (receivingState != 1) inPacket = null; sendSlave.outState = 1;//停止sender thread // if (replySlave.isAlive()) // deprecated method // try {replySlave.stop(); } catch (Throwable st) {} return inPacket; } protected void Bind() throws SocketException { if (inPort != 0) sock = new DatagramSocket(inPort); else sock = new DatagramSocket(); if (Debug) System.out.println("通訊埠 : " + sock.getLocalPort()); } public void Dispose() // { if (sock != null) sock.close(); inPacket = null; outPacket = null; outBuffer = null; inBuffer = null; } } // 注意此類別的功能 class DatagramReplyT extends Thread { private final static boolean Debug = false; DatagramPacket sinPacket; DatagramSocket sinSocket; UDPClient dParent; int fwaiting = 30000; public int receivedState = 0; public DatagramReplyT(DatagramPacket recvPacket, DatagramSocket recvSocket, int totalwaiting) { sinPacket = recvPacket; sinSocket = recvSocket; fwaiting = totalwaiting; } public synchronized int waitOnReply() { try {wait(fwaiting);} catch (InterruptedException intEx) { if (Debug) System.out.println("waitOnReply interrupt!"); } return receivedState; } public synchronized void run() { if (Debug) System.out.println("DatagramReplyT running..."); try { if (Debug) System.out.println("DatagramReplyT receiving..."); sinSocket.receive(sinPacket); receivedState = 1; //接收成功 System.out.println("DatagramReplyT received OK!"); } catch (IOException receiveEx) { System.err.println("receive failed! " + receiveEx); receivedState = -1; }; notify(); } } class DatagramSendT extends Thread { protected final static boolean Debug = false; DatagramPacket soutPacket; DatagramSocket soutSocket; public int outState = 0; //沒有收到但也沒失敗 protected int retryInterval; //以milliseconds為單位 public DatagramSendT(DatagramPacket sendPacket, DatagramSocket sendSocket,int retryTime) { soutPacket = sendPacket; soutSocket = sendSocket; retryInterval = retryTime; } public void run() { if (Debug) System.out.println("DatagramSendT running..."); while (outState == 0) { try { if (Debug) System.out.println("DatagramSendT sending..."); soutSocket.send(soutPacket); outState = 0; if (Debug) System.out.println("DatagramSendT sent ok!"); try {this.sleep(retryInterval);} catch (InterruptedException iEx) { if (Debug) System.err.println("DatagramSendT sleep interrupted!"); outState = -1; }; } catch (IOException sendException) { if (Debug) System.err.println("傳送失敗! " + sendException); outState = -1; }; } } }