zoukankan      html  css  js  c++  java
  • TCPIP+BIO

    转自:https://www.xuebuyuan.com/3215262.html

    在Java中可以基于Socket,ServerSocket来实现TCP/IP+BIO的系统间通信。Socket主要用于实现建立连接及网络IO的操作,ServerSocket主要用于实现服务器端端口的监听及Socket对象的获取。

    Socket实现客户端的关键代码如下:

    /*创建连接,如果域名解析不了会抛出UnkownHostException,当连接不上时会抛出IOException。

           *如果希望控制建立连接的超时,可先调用socket=newSocket(),然后调用socket.connect(SocketAddress endpoint, int timeout) 方法

           */

           Socket socket = new Socket("www.baidu.com", 80);

           /* 将此选项设为非零的超时值时,在与此 Socket 关联的 InputStream 上调用 read() 将只阻塞此时间长度。

            * 如果超过超时值,将引发java.net.SocketTimeoutException,虽然 Socket 仍旧有效。

            * 选项必须在进入阻塞操作前被启用才能生效。

            * 超时值必须是 > 0 的数。超时值为 0 被解释为无穷大超时值。

            */

           socket.setSoTimeout(WAIT_TIME);//read操作时,5s后抛出SocketTimeoutException

           System.out.println("socketcreated!");

           try {

               //获取服务器端返回流

               InputStreamips = socket.getInputStream();

               BufferedReader bin=new BufferedReader(new InputStreamReader(ips));

               //创建向服务器写入流的PrintWriter

               System.out.println("inputstream getted:"+bin);

               PrintWriter out=new PrintWriter(socket.getOutputStream());

               //向服务器发送字符串信息,要注意的是,此次即使写入失败也不会抛出异常信息,

               //并且会一直阻塞到写入操作系统或网络IO出现异常为止。

               out.print("hello");

               //阻塞读取服务器端的返回信息,程序阻塞直到服务器端返回信息或网络IO出现

               //异常为止,如果希望在超过一段时间后就不再阻塞了,那么要在创建Socket对象

               //后调用socket.setSoTimeout(int timeout)

               try{

               String inputline=bin.readLine();

               }catch (SocketTimeoutException e) {

                  System.out.println(e.getMessage()+";waitted time is:"+WAIT_TIME);

               }

           } finally {

               socket.close();

           }

           System.out.println("finished");

    服务器端关键代码如下:

    // 创建server 对本地指定端口的监听,如果端口冲突抛出SocketException,

           //其他网络IO异常抛出IOException

           ServerSocket s = new ServerSocket(LISTENING_PORT);

           //接受客户端建立连接的请求,并返回一个Socket对象,以便和客户端进行交互

           //交互的方式和客户端相同,通过getInputStream()和getOutputStream()

           //来进行读写。

           //此方法会一种阻塞直到有客户端发送建立连接的请求,如果希望限制阻塞时间,可以

           //通过调用setSoTimeout(int timeout)设置超时时间。超过指定时间后会抛出

           //s.setSoTimeout(WAIT_TIME);

           Socket incoming = s.accept();// 等待客户端连接

           if (incoming.isConnected()) {

               log.info("creat aconnect");

           }

    上述代码中,基于Socket和Server能够建立简单的系统间通信。在实际的系统中,通常客户端同时要发送多个请求到服务器端,而服务器端同时要接受多个连接发送的请求。

    为满足客户端能同时发送多个请求到服务器端,最简单的办法就是生成多个Socket。但这时就产生两个问题:

    1.  生成太多的Socket会消耗过多的本地资源,在客户端机器多,服务器端机器少得情况下,客户端生成太多Socket会导致服务器要支撑非常大的连接数;

    2. 生成Socket(建立连接)通常比较慢,因此频繁的创建会导致系统性能不足。

    鉴于此,通常采用连接池的方式来维护Socket是比较好的,这样做,第一可以限制能创建的Socket的数目。第二由于将Socket放入连接池中,可以避免重复创建Socket带来的性能下降问题。比如数据库连接池就是典型例子。但是使用连接池同样有缺点,连接池中Socket数目有限,如果同时要用的Socket请求很多,就会造成激烈的竞争和等待。

    此外,需要注意的一个问题是如何合理控制等待响应的超时时间,如果不设定超时会导致当服务器端出处理变慢时,客户端得相关请求都在做无限的等待,而客户端资源可能是有限的,才这种情况下很容易造成服务器端出现问题时,客户端挂掉。超时时间的具体设定,一般取决于客户端能承受的请求量及服务器端得处理时间。Java TCP/IP+BIO容易通过setSoTimeout方法设置阻塞等待时间。

    为了满足服务器端能同时接受多个连接发送的请求,通常采用的方法是在accept获取Socket之后,将Socket放入一个线程中处理,通常将此方式描述为一个连接一线程。这样服务器可接受多个连接发送请求。这种方式存在的缺点是无论连接上是否有真实的请求,都要耗费一个线程。为避免创建过多的线程导致服务器端资源耗尽,必须限制创建线程的数量。因此采用BIO的情况下服务器端所能支持的并发连接数是有限的。

  • 相关阅读:
    Python格式符号
    Python基础知识
    HDFS 数据流程
    HDFS IO流操作
    HDFS API操作
    Hadoop 客户端环境准备
    Hadop 环境搭建 windows10+hadoop2.7.7
    Hadoop HDFS shell
    Hadoop HDFS 基础
    centos 更改清华源
  • 原文地址:https://www.cnblogs.com/sharpest/p/12702757.html
Copyright © 2011-2022 走看看