java的socket-tcp程式設計中需要注意的東西
阿新 • • 發佈:2019-02-13
題記
這不是一篇關於java的socket程式設計例項,而是記敘那些踩過的坑。
前言
java的socket程式設計最直接的就是用socket相關的API,還有就是結合NIO方式。
socket的API使用起來還是略覺複雜。因此,使用中我還是習慣對其做些封裝。
比如:連結過程。
/**
*
* @param ip
* @param port
* @return
* null, if fail.
*/
public static Socket buildConnection(String ip, int port) {
if (ip==null || port<=0) {
return null;
}
Socket sock = new Socket();
try {
sock.connect(new InetSocketAddress(ip, port), TMO_CONNECTTION);
if (!sock.isConnected()) {
sock.close();
return null;
}
} catch (IOException e) {
e.printStackTrace();
try {
sock.close();
} catch (IOException e1) {
e1.printStackTrace();
}
return null;
}
return sock;
}
用一行程式碼完成連結,程式碼會簡潔的多。
Socket sock = buildConnection(ip, port);
if (sock == null) {
//connect fail.
}
其它的write&read方法也同理。
但在過程中,發現了一些有意思的坑。
InputStream&OutStream
在獲取in和out的stream時,
in:每次獲取的都是同一個物件的引用,
out:每次獲取的都是不同的物件,
這一點通過hashCode就能看出。
輸入只會有一個來源,而輸出可能會有多個。
實際使用中,也不會對單路socket併發地讀和寫,所以也沒啥必要去涉及一類蛋疼問題——考慮到tcp的流概念,那對單路 socket的併發讀寫會是什麼樣。
in和out的關閉都會導致socket的關閉。
輸入&輸出流的關閉相當於順帶呼叫了socket的close方法。想想也應該,要是沒關才奇怪呢。
socket的那些注意事項
對接時,常有人將socket說成是一種介面方式。
socket是一類介面,但它只是程式設計介面,不是通訊方式,http&tcp可以說成是通訊互動的方式但socket不是。
socket的重要狀態屬性:connected、closed。
connected:表明連結狀態;closed:表明開關狀態。
connected&closed關係:
已經connected的socket close後,狀態closed==true,但此時它此時connected狀態還是true。也就是說:關閉連結後,socket還是已連結狀態的。所以,在java中檢測一個socket是否可用,這兩個屬性都需要檢測。另外,此點肯定是java語言的socket程式設計自帶特性,可能也是為了表明這個socket曾經連結過。。。
當Read返回-1時。
“-1”是個很有標誌性的返回值。
Read返回-1表明:Reach the end of the stream,那何時才是end呢?那還得再提下tcp的流概念,tcp的流是雙向的–就像兩個對握雙手的人,左右互牽。
左手代表讀,右手代表寫。當對方撤回右手的時候,你的左手形單影隻,每次Read就立即返回-1了(哪怕你說你可以等也會立即返回呢)。這個時候,你的右手還牽著對方的左手,你寫的話他應該能讀到(這個還沒試過)。這個時候你也把右手撤回的話,那你倆就絃斷無聲各自天涯了。
其實都是常規問題,隨手記敘好習慣!