datagramsocket類是java通過udp通信的途徑。udp仍位于ip層的上面。 你可以用datagramsocket類發送和接收udp資料包。
udp 和tcp
udp工作方式和tcp有點不同。當你通過tcp發送資料時,你先要建立連接配接。一旦tcp連接配接建立了,tcp會保證你的資料傳遞到對端,否則它将告訴你已發生的錯誤。
僅僅用udp來發送資料包(datagrams)到網絡間的某個ip位址。你不能保證資料會不會到達。你也不能保證udp資料包到達接收方的指令。這意味着udp比tcp有更少的協定開銷(無完整檢查流)。
當資料傳輸過程中不在乎資料包是否丢失時,udp就比較适合這樣的資料傳輸。比如,網上的電視信号的傳輸。你希望信号到達用戶端時盡可能地接近直播。是以,如果丢失一兩個畫面,你一點都不在乎。你不希望直播延遲,值想確定所有的畫面顯示在用戶端。你甯可跳過丢失的畫面,希望一直看到最新的畫面。
這種情況也會發生在網上錄影機直播節目中。誰會關心過去發生的什麼,你隻想顯示目前的畫面。你不希望比實際情況慢30s結束,隻因為你想看到錄影機顯示給觀衆的所有畫面。這跟錄影機錄像有點不同。從錄影機錄制畫面到磁盤,你不希望丢失一個畫面。你可能還希望有點延遲,如果有重大的情況發生,就不需要倒回去檢查畫面。
通過java的datagramsocket類發送資料,首先需要建立datagrampacket。如下:
<code>1</code>
<code>buffer = </code><code>new</code> <code>byte</code><code>[</code><code>65508</code><code>];</code>
<code>2</code>
<code>3</code>
<code>inetaddress address = </code><code>new</code> <code>datagrampacket(buffer, buffer.length, address,</code><code>9000</code><code>);</code>
位元組緩沖塊(位元組數組)就是udp資料包中用來發送的資料。緩沖塊上限長度為65508位元組,是單一udp資料包發送的最大的資料量。
資料包構造函數的長度就是緩存塊中用于發送的資料的長度。所有多于最大容量的資料都會被忽略。
包含節點(例如伺服器)位址的inetaddress執行個體攜帶節點(如伺服器)的位址發送的udp資料包。inetaddress類表示一個ip位址(網絡位址)。getbyname()方法傳回帶有一個inetaddress執行個體,該執行個體帶有比對主機名的ip位址。
端口參數是udp端口伺服器用來接收正在監聽的資料。udp端口和tcp端口是不一樣的。一台電腦同時有不同的程序監聽udp和tcp 80端口。
為了發送資料包,你需要建立datagramsocket來發送資料。如下:
<code>datagramsocketdatagramsocket = </code><code>new</code> <code>datagramsocket();</code>
調用send()方法發送資料,像這樣:
<code>datagramsocket.send(packet);</code>
完整示例:
<code>byte</code><code>[] buffer = </code><code>"0123456789"</code><code>.getbytes();</code>
<code>4</code>
<code>5</code>
<code>inetaddressreceiveraddress = inetaddress.getlocalhost();</code>
<code>6</code>
<code>7</code>
<code>dataframpacket packet = </code><code>new</code> <code>datagrampacket( buffer, buffer.length, receiveraddress,</code><code>80</code><code>);</code>
<code>8</code>
從dataframsocket擷取資料時,首先建立dataframpacket ,然後通過datagramsocket類的receive()方法接收資料。例如:
<code>datagramsocketdatagramsocket = </code><code>new</code> <code>datagramsocket(</code><code>80</code><code>);</code>
<code>byte</code><code>[] buffer = </code><code>new</code> <code>byte</code><code>[</code><code>10</code><code>];</code>
<code>datagrampacket packet = </code><code>new</code> <code>datagrampacket(buffer, buffer.length);</code>
<code>datagramsocket.receive(packet);</code>
注意datagramsocket是如何通過傳遞參數80到它的構造器初始化的。這個參數是udp端口的datagramsocket用來接收udp資料包的。像之前提到的,tcp和udp端口是不一樣的,也不重疊。你可以有倆個不同的程序同時在端口80監聽tcp和udp,沒有任何沖突。
第二,位元組緩存塊和datagrampacket建立了。注意datagrampacket是沒有關于節點如何發送資料的資訊的,當建立一個方資料的datagrampacket時,它會直到這個資訊。這就是為什麼我們會用datagrampacket接收資料而不是發送資料。是以沒有目标位址是必須的。
最後,調用datagramsocket的receive()方法。直到資料包接收到為止,這個方法都是阻塞的。
接收的資料位于datagrampacket的位元組緩沖塊。緩沖塊可以通過調用getdata()獲得:
<code>byte</code><code>[] buffer = packet.getdata();</code>
緩沖塊接收了多少的資料需要你去找出來。你用的協定應該定義每個udp包發多少資料,活着定義一個你能找到的資料結束标記。