java tcp socket 與 go tcp socket 的超時

       最近因爲做一個監控系統,在其中用到了大量的socket。由於平時很少用到socket,在使用過程中還是遇到了一些問題的。比如:

      1.socket一般在不主動關閉的情況下阻塞時間一般是有系統本身決定的(這個時間一般都很長)。

      2.超時一般有連接超時,和讀寫超時。對於剛接觸socket的人很容易把代碼中提供的超時方法理解爲連接超時。這就導致了一些錯誤,同時沒有達到自己的預期。(往往會奇怪我明明設置了超時時間,爲什麼拋錯時間和自己設置的對不上

       在做連接監控的時候就用到了對socket的連接超時設置,由於對socket接觸的少就遇到了以上問題。

       在項目中用的是java socket,在之後又看了一下go 的 socket。下面讓我們看一下他們各自的實現:

       我們平時不加超時時間的時候一般都是:

        java :

            // 要連接的服務端IP地址和端口
            String host = "192.168.1.7";
            int port = 6000;
            // 與服務端建立連接
            Socket socket = null;
            try {
                socket = new Socket(host, port);
                // 建立連接後獲得輸出流
                int n = 0;
                String message=this.getName() + "你好" + n;
                socket.getOutputStream().write(message.getBytes("UTF-8"));
            } catch (IOException e) {
                if(num == 0){
                    System.out.println("我連接不上他");
                }
                num++;
                TSocket tSocket = new TSocket();
                tSocket.start();
              e.printStackTrace();
            }

       go :

        conn,err:=net.Dial("tcp","192.168.1.7:6000")
	
	if err != nil {
		fmt.Println(err)
	}
	str := []byte{32, 0, 0, 0, 7, 85, 35, 160, 176, 7, 226, 12, 18, 15, 45, 0}

	//向連接端發送一個數據
	_,err=conn.Write(str)
	if err != nil {
		fmt.Println(err)
	}
	//讀取連接端返回來的數據,
	result,err:=ioutil.ReadAll(conn)
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(string(result))

     在java中爲我們socket.setSoTimeOut()來設置超時時間,在go中這是conn.SetDialLine(),conn.SetReadDialLine(),

conn.SetWriteDialLine()。

    剛開始用socket的人會理所當然的認爲這兩個是設置的連接超時。就會導致上面所說的問題。

    java中的socket.setSoTimeOut()是設置socket的讀超時。設置後在讀超時後,就會拋出java.net.SocketTimeoutException: Read timed out

    go中的conn.SetDialLine()是設置socket的讀寫超時。相當於conn.SetReadDialLine()和conn.SetWriteDialLine()。同時conn.SetDialLine()設置的距離讀寫的結束時間,而不是直接就是設置每次讀寫的超時時間。

    其實想實現對連接超時時間的設置很簡單,java和go都爲我們實現了:

    java:

socket = new Socket(host, port);


修改爲:
 

socket = new Socket();
socket.connect(new InetSocketAddress(host, port), 5000);//地址,超時時間

   go:

conn,err:=net.Dial("tcp","192.168.1.7:6000")


修改爲 :


conn,err:=net.DialTimeOut("tcp","192.168.1.7:6000",5*time.Second)//連接類型,地址,超時時間

  在java中通過socket.connect()超時時間,同時單位是毫秒。

  在go中通過net.DialTimeOut設置。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章