1. 程式人生 > >java的socket-tcp程式設計中需要注意的東西

java的socket-tcp程式設計中需要注意的東西

題記

這不是一篇關於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了(哪怕你說你可以等也會立即返回呢)。這個時候,你的右手還牽著對方的左手,你寫的話他應該能讀到(這個還沒試過)。這個時候你也把右手撤回的話,那你倆就絃斷無聲各自天涯了。
其實都是常規問題,隨手記敘好習慣!