DatagramChannel

DatagramChannel
  最后一個socket通道是DatagramChannel。正如SocketChannel對應Socket,ServerSocketChannel對應ServerSocket,每一個DatagramChannel對象也有一個關聯(lián)的DatagramSocket對象。不過原命名模式在此并未適用:“DatagramSocketChannel”顯得有點笨拙,因此采用了簡潔的“DatagramChannel”名稱。正如SocketChannel模擬連接導向的流協(xié)議(如TCP/IP),DatagramChannel則模擬包導向的無連接協(xié)議(如UDP/IP):

創(chuàng)建DatagramChannel的模式和創(chuàng)建其他socket通道是一樣的:調用靜態(tài)的open( )方法來創(chuàng)建一個新實例。新DatagramChannel會有一個可以通過調用socket( )方法獲取的對等DatagramSocket對象。DatagramChannel對象既可以充當服務器(監(jiān)聽者)也可以充當客戶端(發(fā)送者)。如果您希望新創(chuàng)建的通道負責監(jiān)聽,那么通道必須首先被綁定到一個端口或地址/端口組合上。綁定DatagramChannel同綁定一個常規(guī)的DatagramSocket沒什么區(qū)別,都是委托對等socket對象上的API實現(xiàn)的:

DatagramChannel channel = DatagramChannel.open( );
DatagramSocket socket = channel.socket( );
socket.bind (new InetSocketAddress (portNumber));

DatagramChannel是無連接的。每個數(shù)據(jù)報(datagram)都是一個自包含的實體,擁有它自己的目的地址及不依賴其他數(shù)據(jù)報的數(shù)據(jù)凈荷。與面向流的的socket不同,DatagramChannel可以發(fā)送單獨的數(shù)據(jù)報給不同的目的地址。同樣,DatagramChannel對象也可以接收來自任意地址的數(shù)據(jù)包。每個到達的數(shù)據(jù)報都含有關于它來自何處的信息(源地址)。

一個未綁定的DatagramChannel仍能接收數(shù)據(jù)包。當一個底層socket被創(chuàng)建時,一個動態(tài)生成的端口號就會分配給它。綁定行為要求通道關聯(lián)的端口被設置為一個特定的值(此過程可能涉及安全檢查或其他驗證)。不論通道是否綁定,所有發(fā)送的包都含有DatagramChannel的源地址(帶端口號)。未綁定的DatagramChannel可以接收發(fā)送給它的端口的包,通常是來回應該通道之前發(fā)出的一個包。已綁定的通道接收發(fā)送給它們所綁定的熟知端口(wellknown port)的包。數(shù)據(jù)的實際發(fā)送或接收是通過send( )和receive( )方法來實現(xiàn)的:

/**
 * @author qiz
 */
public class DatagramChannel1 {
    public static void main(String[] args) throws IOException {
        DatagramChannel datagramChannel = DatagramChannel.open();

        datagramChannel.configureBlocking(false);
        ByteBuffer allocate = ByteBuffer.allocate(1024);
        Scanner scanner = new Scanner(System.in);
        while (scanner.hasNext()){
            String str = scanner.next();
            allocate.put((new Date().toString()+"\n"+str).getBytes());
            allocate.flip();
            datagramChannel.send(allocate,new InetSocketAddress("127.0.0.1",9898));
            allocate.clear();
        }
        datagramChannel.close();
    }
}
/**
 * @author qiz
 */
public class DatagramChannel2 {
    public static void main(String[] args) throws IOException {
        DatagramChannel datagramChannel = DatagramChannel.open();

        datagramChannel.configureBlocking(false);
        datagramChannel.bind(new InetSocketAddress(9898));

        Selector selector = Selector.open();

        datagramChannel.register(selector, SelectionKey.OP_READ);
        while (selector.select() > 0){
            Iterator<SelectionKey> iterator = selector.selectedKeys().iterator();
            while (iterator.hasNext()){
                SelectionKey next = iterator.next();
                if (next.isReadable()){
                    ByteBuffer allocate = ByteBuffer.allocate(1024);
                    datagramChannel.receive(allocate);
                    allocate.flip();
                    System.out.println(new String(allocate.array(),0,allocate.limit()));
                    allocate.clear();
                }
            }
            iterator.remove();
        }
    }
}
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容