亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

淺談java socket的正確關(guān)閉姿勢(shì)

 更新時(shí)間:2021年06月15日 14:49:52   作者:wkCaeser_  
這篇文章主要介紹了java socket的正確關(guān)閉姿勢(shì),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

java socket對(duì)應(yīng)的是網(wǎng)絡(luò)協(xié)議中的tcp,tcp的三次握手、四次揮手、11中狀態(tài)什么的這里就不說(shuō)了,不知道大家平常使用socket的時(shí)候如果不注意的情況下,會(huì)不會(huì)遇到各種異常報(bào)錯(cuò)。

例如:

java.net.SocketException:socket is closed

錯(cuò)誤提示的出現(xiàn)場(chǎng)景:

自己主動(dòng)關(guān)閉了socket,但是之后還從里面讀寫(xiě)數(shù)據(jù)

Software caused connection abort: socket write error

錯(cuò)誤提示的出現(xiàn)場(chǎng)景:

對(duì)方已經(jīng)關(guān)閉socket,依舊向?qū)Ψ綄?xiě)數(shù)據(jù)

connection reset (by peer)

錯(cuò)誤提示出現(xiàn)的場(chǎng)景:

一端socket被關(guān)閉,另一端仍然發(fā)送數(shù)據(jù),發(fā)送的第一個(gè)數(shù)據(jù)包 connection reset by peer

一端socket退出,退出時(shí)為關(guān)閉連接,另一端讀數(shù)據(jù) connection reset

所以在使用socket時(shí),需要約定好雙方讀寫(xiě)完成的條件,然后關(guān)閉輸入輸出流:

socket.shutdownInput();
socket.shutdownOutput();

即當(dāng)一方寫(xiě)入完成后,調(diào)用shutdownOutput關(guān)閉輸出流,這時(shí)候?qū)Ψ降膔ead方法就會(huì)返回-1,這時(shí)候?qū)Ψ骄椭滥銓?xiě)完了,對(duì)方可以關(guān)閉輸入流,然后等待對(duì)方寫(xiě)入完成調(diào)用shutdownOutput后己方再調(diào)用shutdownInput,雙方就正常關(guān)閉了輸入輸出流,這時(shí)候socket就不會(huì)出現(xiàn)異常了。

下面是一個(gè)socket交互的例子:

server端

public class OioServer {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = new ServerSocket(8080);
        while (true) {
            Socket socket = serverSocket.accept();
            System.out.println("socket = " + socket);
            new Thread(() -> {
                try {
                    InputStream in = socket.getInputStream();
                    OutputStream out = socket.getOutputStream();
                    out.write("hello! I get your message that is follow".getBytes(Charset.forName("UTF-8")));
                    byte[] buf = new byte[1024];
                    int len;
                    while ((len = in.read(buf)) != -1) {
                        System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));
                        out.write(buf, 0, len);
                    }
                    out.write("\n end \n".getBytes(Charset.forName("UTF-8")));
                    out.flush();
                    socket.shutdownInput();
                    socket.shutdownOutput();
                } catch (IOException e) {
                    e.printStackTrace();
                }finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
}

client端

public class OioClient {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 8080);
        InputStream in = socket.getInputStream();
        new Thread(() -> {
            BufferedInputStream bufferIn = new BufferedInputStream(in);
            byte[] buf = new byte[1024];
            try {
                int len;
                while ((len = bufferIn.read(buf)) != -1) {
                    System.out.print(new String(buf, 0, len, Charset.forName("UTF-8")));
                }
            }catch (Exception e) {
                e.printStackTrace();
            }
            try {
                socket.shutdownInput();
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();
        OutputStream out = socket.getOutputStream();
        int cout = 10;
        while (cout-- > 0) {
            out.write(("this time is " + System.currentTimeMillis() + "\n").getBytes("UTF-8"));
        }
        socket.shutdownOutput();
    }
}

java socket - 半關(guān)閉

通常,使用關(guān)閉輸出流來(lái)表示輸出已經(jīng)結(jié)束。但在進(jìn)行網(wǎng)絡(luò)通信時(shí)則不能這樣做。因?yàn)槲覀冴P(guān)閉輸出流時(shí),該輸出流對(duì)應(yīng)的Socket也將隨之關(guān)閉,這樣程序?qū)o(wú)法再?gòu)脑搒ocket中讀取數(shù)據(jù)。

為了應(yīng)付這種情況,socket提供了兩個(gè)半關(guān)閉的方法用來(lái)只關(guān)閉socket的輸入流或者輸出流,用以表示輸出數(shù)據(jù)已經(jīng)發(fā)送完成。

方法詳情:

shutdownInput():關(guān)閉該socket的輸入流,程序還可以通過(guò)該socket的輸出流輸出數(shù)據(jù);

shutdownOutput():關(guān)閉該socket的輸出流,程序還可以通過(guò)該socket的輸入流讀取數(shù)據(jù)。

當(dāng)調(diào)用shutdownInput()或shutdownOutput()方法關(guān)閉輸入流或輸出流后,該socket處于半關(guān)閉狀態(tài)。

此時(shí)可以使用isInputShutdown()或isOutputShutdown()來(lái)判斷該socket是否處于半讀狀態(tài)或半寫(xiě)狀態(tài)。

需要注意的是,即使同一個(gè)socket先后調(diào)用shutdownInput()和shutdownInput()方法,該socket實(shí)例仍然沒(méi)有被關(guān)閉,只是該socket既不能輸出數(shù)據(jù)也不能讀取數(shù)據(jù)而已。

當(dāng)調(diào)用shutdownInput()或shutdownOutput()方法關(guān)閉了輸入流或輸出流之后,該socket無(wú)法再次打開(kāi)輸出流或輸入流,因此這種做法不適合需要保持持久通信狀態(tài)的交互式應(yīng)用。

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java中的對(duì)象流總結(jié)(必看篇)

    Java中的對(duì)象流總結(jié)(必看篇)

    下面小編就為大家?guī)?lái)一篇Java中的對(duì)象流總結(jié)(必看篇)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-04-04
  • 詳解Spring注解--@Autowired、@Resource和@Service

    詳解Spring注解--@Autowired、@Resource和@Service

    本篇文章主要介紹最重要的三個(gè)Spring注解,也就是@Autowired、@Resource和@Service,具有很好的參考價(jià)值。下面跟著小編一起來(lái)看下吧
    2017-05-05
  • 使用JSONObject.toJSONString 過(guò)濾掉值為空的key

    使用JSONObject.toJSONString 過(guò)濾掉值為空的key

    這篇文章主要介紹了使用JSONObject.toJSONString 過(guò)濾掉值為空的key,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-03-03
  • java兩個(gè)數(shù)組合并為一個(gè)數(shù)組的幾種方法

    java兩個(gè)數(shù)組合并為一個(gè)數(shù)組的幾種方法

    這篇文章主要給大家介紹了關(guān)于java兩個(gè)數(shù)組合并為一個(gè)數(shù)組的幾種方法,最近在寫(xiě)代碼時(shí)遇到了需要合并兩個(gè)數(shù)組的需求,文中將每種方法都介紹的非常詳細(xì),需要的朋友可以參考下
    2023-07-07
  • 解決spring-data-jpa mysql建表編碼問(wèn)題

    解決spring-data-jpa mysql建表編碼問(wèn)題

    這篇文章主要介紹了解決spring-data-jpa mysql建表編碼問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-07-07
  • 將ResultSet中得到的一行或多行結(jié)果集封裝成對(duì)象的實(shí)例

    將ResultSet中得到的一行或多行結(jié)果集封裝成對(duì)象的實(shí)例

    這篇文章主要介紹了將ResultSet中得到的一行或多行結(jié)果集封裝成對(duì)象的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-05-05
  • Spring Boot利用Docker快速部署項(xiàng)目的完整步驟

    Spring Boot利用Docker快速部署項(xiàng)目的完整步驟

    這篇文章主要給大家介紹了關(guān)于Spring Boot利用Docker快速部署項(xiàng)目的完整步驟,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Spring Boot具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • Spring StopWatch使用實(shí)例詳解

    Spring StopWatch使用實(shí)例詳解

    這篇文章主要介紹了Spring StopWatch使用實(shí)例詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 舉例詳解Java中的訪問(wèn)權(quán)限修飾符

    舉例詳解Java中的訪問(wèn)權(quán)限修飾符

    這篇文章主要介紹了舉例詳解Java中的訪問(wèn)權(quán)限修飾符,是Java入門(mén)學(xué)習(xí)中的基礎(chǔ)知識(shí),需要的朋友可以參考下
    2015-08-08
  • 親手教你IDEA2020.3創(chuàng)建Javaweb項(xiàng)目的步驟詳解

    親手教你IDEA2020.3創(chuàng)建Javaweb項(xiàng)目的步驟詳解

    這篇文章主要介紹了IDEA2020.3創(chuàng)建Javaweb項(xiàng)目的步驟詳解,本文是小編手把手教你,通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2021-03-03

最新評(píng)論