java中DataGramSocket類中connect方法詳解

Java 的UDP的實現主要靠的是DataGramSocket類來實現,基礎的東西網上多的是,例子也是一大片的。這裡如果想學最基礎的東西建議不要怎麼看,本文主要對UDP的連接問題的一個概述:

方法/步驟

Connect:這個是jdk api文檔的東西

1. public void connect(InetAddress address,int port)

將套接字連接到此套接字的遠程地址。當套接字連接到遠程地址時,包就只能從該地址發送或接收。默認情況下不連接數據報套接字。

如果套接字要連接的遠程目標不存在或不可到達,並且收到了該地址的目標不可達 ICMP 包,那麼後續發送和接收的調用可能會拋出 PortUnreachableException。注意,不能保證一定拋出該異常。

在連接時檢查調用者對給定主機和埠的發送和接收數據報權限。當連接建立起來後,接收和發送除了對包和套接字的地址和埠進行匹配外,對傳入和傳出的包將不再執行任何安全性檢查。對於發送操作,如果設置了包的地址並且包的地址和套接字的地址不匹配,則將拋出 IllegalArgumentException。連接到多播地址的套接字只能用於發送包。

參數:

address- 套接字的遠程地址。

port- 套接字的遠程埠。

拋出:

IllegalArgumentException- 如果地址為 null,或埠超出了範圍。

SecurityException- 如果不允許調用者向此地址和埠發送也不允許從此地址接收數據報。

另請參見:

disconnect(), send(java.net.DatagramPacket), receive(java.net.DatagramPacket)

2.connect

public void connect(SocketAddress addr)

throws SocketException

將此套接字連接到遠程套接字地址(IP 地址 + 埠號)。

參數:

addr- 遠程地址。

拋出:

SocketException- 如果連接失敗

IllegalArgumentException- 如果 addr 為 null 或者 addr 是不受此套接字支持的 SocketAddress 子類。

從以下版本開始:

1.4

另請參見:

connect(java.net.InetAddress, int)

首先:介紹下這兩個方法,其實SocketAddress類就是InetAddress和埠號的封裝,

我們所謂的「應用的IP位址」都是由IP位址 (InetAddress)和埠號(port)來實現的

在我們應用的時候Java為了給我們封裝這個IP位址就於是給我們提供了一個SocketAddress類。

所以歸根結底這兩個方法還是一樣的 ,只不過就是改了下形式。

我當時的疑惑:當時在看API文檔的時候,它裡面就有一個Connect方法但是,明明是UDP是面向無連接的,所以由此產生疑惑。

在網上搜了一下,還沒有將這個問題的。我去煩死我了,所以在SRC原始碼碼中

下面看看jdk給出的原始碼:

/**

* Sends a datagram packet from this socket. The

* <code>DatagramPacket</code> includes information indicating the

* data to be sent, its length, the IP address of the remote host,

* and the port number on the remote host.

*

* <p>If there is a security manager, and the socket is not currently

* connected to a remote address, this method first performs some

* security checks. First, if <code>p.getAddress().isMulticastAddress()</code>

* is true, this method calls the

* security manager's <code>checkMulticast</code> method

* with <code>p.getAddress()</code> as its argument.

* If the evaluation of that expression is false,

* this method instead calls the security manager's

* <code>checkConnect</code> method with arguments

* <code>p.getAddress().getHostAddress()</code> and

* <code>p.getPort()</code>. Each call to a security manager method

* could result in a SecurityException if the operation is not allowed.

*

* @param      p   the <code>DatagramPacket</code> to be sent.

*

* @exception  IOException  if an I/O error occurs.

* @exception  SecurityException  if a security manager exists and its

*             <code>checkMulticast</code> or <code>checkConnect</code>

*             method doesn't allow the send.

* @exception  PortUnreachableException may be thrown if the socket is connected

*             to a currently unreachable destination. Note, there is no

*             guarantee that the exception will be thrown.

* @exception  java.nio.channels.IllegalBlockingModeException

*             if this socket has an associated channel,

*             and the channel is in non-blocking mode.

* @exception  IllegalArgumentException if the socket is connected,

*             and connected address and packet address differ.

*

* @see        java.net.DatagramPacket

* @see        SecurityManager#checkMulticast(InetAddress)

* @see        SecurityManager#checkConnect

* @revised 1.4

* @spec JSR-51

*/

翻譯:從此套接字發送數據報包。DatagramPacket 包含的信息指示:將要發送的數據、其長度、遠程主機的 IP 地址和遠程主機的埠號。

如果存在安全管理器,且套接字當前沒有連接到遠程地址,則此方法首先執行某些安全性檢查。首先,如果 p.getAddress().isMulticastAddress() 為 true,則此方法以 p.getAddress() 作為參數調用安全管理器的 checkMulticast 方法。如果該表達式的值為 false,此方法改為調用安全管理器的以 p.getAddress().getHostAddress() 和 p.getPort() 為參數的 checkConnect 方法。如果不允許該操作,則每次調用安全管理器方法都會導致 SecurityException。

參數:

p- 將要發送的 DatagramPacket。

拋出:

IOException- 如果發生 I/O 錯誤。

SecurityException- 如果安全管理器存在並且其 checkMulticast 或 checkConnect 方法不允許進行發送。

PortUnreachableException- 套接字連接到當前不可達的目標時可能拋出。注意,不能保證一定拋出該異常。

IllegalBlockingModeException- 如果此套接字具有相關聯的通道,且通道處於非阻塞模式。

另請參見:

DatagramPacket, SecurityManager.checkMulticast(InetAddress), SecurityManager.checkConnect(java.lang.String, int)

public void send(DatagramPacket p) throws IOException  {

InetAddress packetAddress = null;

synchronized (p) {

if (isClosed())

throw new SocketException("Socket is closed");

checkAddress (p.getAddress(), "send");

if (connectState == ST_NOT_CONNECTED) {

// check the address is ok wiht the security manager on every send.

SecurityManager security = System.getSecurityManager();

// The reason you want to synchronize on datagram packet

// is because you dont want an applet to change the address

// while you are trying to send the packet for example

// after the security check but before the send.

if (security != null) {

if (p.getAddress().isMulticastAddress()) {

security.checkMulticast(p.getAddress());

} else {

security.checkConnect(p.getAddress().getHostAddress(),

p.getPort());

}

}

} else {

// we're connected

packetAddress = p.getAddress();

if (packetAddress == null) {

p.setAddress(connectedAddress);

p.setPort(connectedPort);

} else if ((!packetAddress.equals(connectedAddress)) ||

p.getPort() != connectedPort) {

throw new IllegalArgumentException("connected address " +

"and packet address" +

" differ");

}

}

// Check whether the socket is bound

if (!isBound())

bind(new InetSocketAddress(0));

// call the  method to send

getImpl().send(p);

}

}

從 ST_NOT_CONNECTED(標記是否連接的一個int型變量

static final int ST_NOT_CONNECTED = 0)

如果未連接則試用DataGramPacket裡面的IP位址進行傳輸,如果已經連接上了,則用連接到的IP和埠號來傳輸,(看紅色斜體加粗的代碼):這樣問題就迎刃而解了。

Java這樣做到的好處。限制通信的單向性,有時不需要進行多向通信,這樣跟方便。相當於通道通信。編程多的應該能體會到,這會很方便我們實現功能,再也不用封裝IP在Data里了。

相關文章

  1. ASP.NET中水晶報表的使用方法詳解

    前一段時間,由於在項目中要用到報表做統計,所以我學習了一下ASP.NET水晶報表的使用.水晶報表的執行模式(也就是取數據的方法)可以分為兩種: 第一種是Pull模式:被請求時,水晶報表直接根據指定的驅 ...
  2. Word 2016中大綱視圖的使用方法詳解

    大綱視圖可以將文檔的標題分級顯示,使文檔結構層次分明,易於編輯.還可以設置文檔和顯示標題的層級結構,並且摺疊和展開各種層級的文檔.本經驗接下來介紹Word 2016中使用大綱視圖的方法和具體步驟. 工 ...
  3. 電腦中丟失文件的恢複方法詳解

    我們現在經常需要用到電腦,無論是在工作中還是在學習上.而既然我們有用到電腦,那麼電腦上就會存儲有一些比較重要的數據,有時候在操作上不小心,就將這些文件刪除了,咋辦?又或者,是在自己還沒有反應過來的情況 ...
  4. excel表格中left函數的使用方法詳解

    因為excel表格是外國人開發的,所以,使用的語言及用法等等均是外語,更確切的說是英語,函數公式也不例外. "left"英文意思是:左邊,左邊的,在左邊.在excel表格中,也是這 ...
  5. word中鍵盤功能區鍵位使用方法詳解

    本文主要講述在word辦公軟體中使用鍵盤功能區鍵位提高辦公效率和速度的詳解介紹,通過學習並了解鍵盤功能區鍵位的使用原理及效果說明. 工具/原料 word 鍵盤 方法/步驟 首先以下圖為例進行說明,下圖 ...
  6. JAVA語言環境變量臨時配置方法詳解

    如果我們想要在別人的電腦上編寫JAVA程序並且運行就需要對環境變量進行臨時配置,那麼該怎麼配置呢?現在菩提就為大家詳細介紹在DOS窗口中配置臨時環境變量的方法. 工具/原料 JDK 方法/步驟 在DO ...
  7. Java中的main()方法詳解

    在Java中,main()方法是Java應用程式的入口方法,,因為JAVA是在C++的基礎上開發的語言,main也是c++的程序入口,這裡就說一下JAVA的main方法.也就是說,程序在運行的時候,第 ...
  8. 在java的vo類中快速寫setter和getter方法

    如何在java的vo類中快速寫setter和getter方法,請繼續往下看 工具/原料 eclipse 計算機 方法/步驟 首先找到一個java項目,打開java項目的vo類文件,如圖所示 然後在vo ...
  9. Java中Scanner.useDelimiter( )方法詳解

    在Java語言中,格式化輸入是通過類java.util.Scanner來完成的.默認情況下,Scanner是使用"空白"作為分隔符將輸入分解為標記,然後使用它所提供的不同的next ...
  10. Java中String類的主要方法及應用

    Java語言是美國Sun公司(Stanford University Network/史丹福大學網絡公司),在1995年推出的高級的編程語.隨著Java語言的不斷推廣和發展,Java語言已經成為目前主 ...
  11. excel中vba函數inputbox的使用方法詳解

    excel中vba函數inputbox的使用方法詳解 工具/原料 excel2013 更多經驗請關注,如果幫到了你,請在上方給個投票謝謝支持.好人一生平安. 先頂後看年薪百萬,如果幫到了你,幫忙給個好 ...
  12. Windows7系統中安裝字體的兩種方法詳解

    Windows7系統中自帶的字體較少,我們往往需要另外安裝更豐富的字體.本篇經驗就來介紹一下在Windows7系統中安裝字體的兩種方法. 工具/原料 Windows7 一.使用完全方式安裝字體 打開字 ...
  13. excel中vba里使用offset的方法詳解

    小編致力於為大家奉獻最有效的經驗,讓大家能夠解決掉問題,但是大家也都知道,每個人遇到的情況都是不一樣的,大家在看小編經驗的同時,除了跟隨操作,也需要自己的思考,舉一反三的解決問題,這樣才會變得更加有內 ...
  14. C++中CallBack類的使用方法

    使用CallBack類,可按以下步驟進行: 1.確定程序中哪些對象間存在關係,需要建立消息連接.並確定在各特定消息連接關係中,哪個對象是事件對象,哪個對象是回調對象. 2.事件對象類和回調對象類都必須 ...
  15. java中String類中的常用方法有哪些?

    java中String類中的常用方法 工具/原料 java 方法/步驟 @Test // 測試字符串的lenght()方法 public void testStringLenght() {  // 字 ...
  16. 足球經理2014如何比賽中換人方法詳解

    <足球經理2014>是一款可玩性相當高的遊戲,很多玩家都想知道比賽中如何換人,今天小編就跟大家分享一下換人的方法,其實方法還是比較簡單的.   比賽中換人方法: 比賽的時候點球員上面的按鈕 ...
  17. wordpress中頁面調用和分類目錄調用的方法詳解

    在論壇上有好多同學都問起了關於首頁分類目錄和頁面的調用問題,對這個問題搞了好長時間,始終搞不好!想做到行動日誌的那種頭部效果! 導航調用的是文章列表,其實就是調用的分類目錄,而下面是調用的頁面,可以直 ...
  18. win7中快捷方式去箭頭方法詳解

    桌面快捷方式是在Windows上安裝軟體的時候,在桌面建立一個相應的快捷圖標,並且有一個快捷標示的小箭頭.很多人覺得小箭頭不怎麼好看,就會應用各種方法去除它,優化.美化類工具軟體大多也提供了去除快捷圖 ...
  19. 在踩踏事故中的自救方法詳解【圖】

    踩踏,是一種古往今來都會發生的事故.每年的動物的大遷移的過程中都有很多食草動物死於同類的蹄子之下.而人群的踩踏事故更是在歷史有過血淚的教訓.人類是生來就是比較喜歡群居的動物,多數人對少數人天然就有著吸 ...
  20. hibernate中Session.update()方法詳解

    hibernate中Session.update()方法詳解 工具/原料 hibernate eclipse 方法/步驟 Session的update方法:使一個游離對象轉化為持久化對象,並且計劃執行 ...