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设置。

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