Java使用DatagramSocket

來源:互聯網
上載者:User

標籤:多少   第一個   實參   art   包含   目的   伺服器   end   51cto   

轉自:http://book.51cto.com/art/201203/322540.htm

 

Java使用DatagramSocket代表UDP協議的Socket,DatagramSocket本身只是碼頭,不維護狀態,不能產生IO流,它的唯一作用就是接收和發送資料報,Java使用DatagramPacket來代表資料報,DatagramSocket接收和發送的資料都是通過DatagramPacket對象完成的。

先看一下DatagramSocket的構造器。

DatagramSocket():建立一個DatagramSocket執行個體,並將該對象綁定到本機預設IP地址、本機所有可用連接埠中隨機播放的某個連接埠。

DatagramSocket(int prot):建立一個DatagramSocket執行個體,並將該對象綁定到本機預設IP地址、指定連接埠。

DatagramSocket(int port, InetAddress laddr):建立一個DatagramSocket執行個體,並將該對象綁定到指定IP地址、指定連接埠。

通過上面三個構造器中的任意一個構造器即可建立一個DatagramSocket執行個體,通常在建立伺服器時,建立指定連接埠的DatagramSocket執行個體--這樣保證其他用戶端可以將資料發送到該伺服器。一旦得到了DatagramSocket執行個體之後,就可以通過如下兩個方法來接收和發送資料。

receive(DatagramPacket p):從該DatagramSocket中接收資料報。

send(DatagramPacket p):以該DatagramSocket對象向外發送資料報。

從上面兩個方法可以看出,使用DatagramSocket發送資料報時,DatagramSocket並不知道將該資料報發送到哪裡,而是由DatagramPacket自身決定資料報的目的地。就像碼頭並不知道每個集裝箱的目的地,碼頭只是將這些集裝箱發送出去,而集裝箱本身包含了該集裝箱的目的地。

下面看一下DatagramPacket的構造器。

DatagramPacket(byte[] buf,int length):以一個空數組來建立DatagramPacket對象,該對象的作用是接收DatagramSocket中的資料。

DatagramPacket(byte[] buf, int length, InetAddress addr, int port):以一個包含資料的數組來建立DatagramPacket對象,建立該DatagramPacket對象時還指定了IP地址和連接埠--這就決定了該資料報的目的地。

DatagramPacket(byte[] buf, int offset, int length):以一個空數組來建立DatagramPacket對象,並指定接收到的資料放入buf數組中時從offset開始,最多放length個位元組。

DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):建立一個用於發送的DatagramPacket對象,指定發送buf數組中從offset開始,總共length個位元組。

當Client/Server程式使用UDP協議時,實際上並沒有明顯的伺服器端和用戶端,因為兩方都需要先建立一個DatagramSocket對象,用來接收或發送資料報,然後使用DatagramPacket對象作為傳輸資料的載體。通常固定IP地址、固定連接埠的DatagramSocket對象所在的程式被稱為伺服器,因為該DatagramSocket可以主動接收用戶端資料。

在接收資料之前,應該採用上面的第一個或第三個構造器產生一個DatagramPacket對象,給出接收資料的位元組數組及其長度。然後調用DatagramSocket 的receive()方法等待資料報的到來,receive()將一直等待(該方法會阻塞調用該方法的線程),直到收到一個資料報為止。如下代碼所示:

    // 建立一個接收資料的DatagramPacket對象      DatagramPacket packet=new DatagramPacket(buf, 256);      // 接收資料報      socket.receive(packet);   

 

在發送資料之前,調用第二個或第四個構造器建立DatagramPacket對象,此時的位元組數組裡存放了想發送的資料。除此之外,還要給出完整的目的地址,包括IP地址和連接埠號碼。發送資料是通過DatagramSocket的send()方法實現的,send()方法根據資料報的目的地址來尋徑以傳送資料報。如下代碼所示:

// 建立一個發送資料的DatagramPacket對象  DatagramPacket packet = new DatagramPacket(buf, length, address, port);  // 發送資料報  socket.send(packet); 

使用DatagramPacket接收資料時,會感覺DatagramPacket設計得過於煩瑣。開發人員只關心該DatagramPacket能放多少資料,而DatagramPacket是否採用位元組數組來儲存資料完全不想關心。但Java要求建立接收資料用的DatagramPacket時,必須傳入一個空的位元組數組,該數組的長度決定了該DatagramPacket能放多少資料,這實際上暴露了DatagramPacket的實現細節。接著DatagramPacket又提供了一個getData()方法,該方法又可以返回Datagram Packet對象裡封裝的位元組數組,該方法更顯得有些多餘--如果程式需要擷取DatagramPacket裡封裝的位元組數組,直接存取傳給 DatagramPacket構造器的位元組數組實參即可,無須調用該方法。

當伺服器端(也可以是用戶端)接收到一個DatagramPacket對象後,如果想向該資料報的寄件者"反饋"一些資訊,但由於UDP協議是面向非串連的,所以接收者並不知道每個資料報由誰發送過來,但程式可以調用DatagramPacket的如下3個方法來擷取寄件者的IP地址和連接埠。

InetAddress getAddress():當程式準備發送此資料報時,該方法返回此資料報的目標機器的IP地址;當程式剛接收到一個資料報時,該方法返回該資料報的發送主機的IP地址。

int getPort():當程式準備發送此資料報時,該方法返回此資料報的目標機器的連接埠;當程式剛接收到一個資料報時,該方法返回該資料報的發送主機的連接埠。

SocketAddress getSocketAddress():當程式準備發送此資料報時,該方法返回此資料報的目標SocketAddress;當程式剛接收到一個資料報時,該方法返回該資料報的發送主機的SocketAddress。

getSocketAddress()方法的傳回值是一個SocketAddress對象,該對象實際上就是一個IP地址和一個連接埠號碼。也就是說,SocketAddress對象封裝了一個InetAddress對象和一個代表連接埠的整數,所以使用SocketAddress對象可以同時代表IP地址和連接埠。

Java使用DatagramSocket

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.