Java学习(十一)

Java学习(十一)

网络编程

  1. 基本网络支持

    1. InetAddress

      其有两个子类分别表示ipv4和ipv6,即Inet4AddressInet6Address

      该类没有构造器,通过两个静态方法:getByName(String host)getByAddress(byte[] addr)来获取实例

      通过实例方法获取主机名、IP地址:getHostAddress()getHostName()getLocalHost()

      测试是否可达:isReachable(int timeout)

    2. URLDecoderURLEncoder

      这两个类用于完成普通字符串和application/x-www-form-urlencoded MIME字符串之间的转换,后者是特殊编码的字符串,当URL中包含非西欧字符时(例如浏览器中的中文),就会使用上述编码进行转换。

      URLDecoder用于把后者转换成前者,URLEncoder则相反。

      形参都是(String s, String enc)enc是字符集

    3. URLURLConnectionURLPermission

      URL类包含如下实例方法:

      getFile():获取资源名

      getHost():获取主机名

      getPath():获取URL的路径部分

      getPort():int端口号

      getProtocol

      getQuery():获取查询字符串

      URLConnection代表与URL引用的远程对象的通信连接(TCP连接),由URL类实例的openConnection()返回得到,HttpURLConnection表示与URL之间的HTTP连接。URLConnection 可以走邮件、文件传输协议,而HttpURLConnection 就单指浏览器的HTTP协议

      InputStream openStream(),得到一个读取该URL资源的InputStream

      URLPermission用于管理HttpURLConnection的权限问题

      从创建URL连接、发送请求,到读取URL资源一般需要的步骤如下:

      1. openConnection()获取URLConnection对象
      2. 设置URLConnection参数和普通请求属性
      3. 发送GET请求:直接用connect()建立实际连接即可;发送POST请求:获取URLConnection实例对应的输出流来发送请求参数(必须设置setDoOutput(true);setDoInput(true);
      4. 等待远程资源变成可用,通过访问头字段或通过输入流读取远程资源的数据
  2. TCP网络编程

    1. 建立服务端

      使用ServerSocket类,用于监听客户端请求

      Socket accpet():返回与客户端对应的Socket对象;若没有客户端连接则一直处于阻塞状态

      close();:关闭该ServerSocket

      构造器:

      ServerSocket(int port):指定端口建立

      ServerSocket(int port, int backlog):启用用于改变连接队列长度的backlog参数

      ServerSocket(int port, int backlog, InetAddress localAddr):服务端有多个IP,将该实例绑定到指定的IP

    2. 通信

      使用Socket类进行通信,其构造器需要指定远程主机和其端口

      InputStream getIntputStream():得到Socket的输入流

      OutputStream getOutputStream():得到Socket的输出流

      setSoTimeout(int timeout):超过此时间认为超时通信失败,如果超时后仍然操作Socket,那么会抛出SocketTimeoutException异常

      判断建立连接超时:先创建无连接的Socket,再调用connect(InetAddress host, int timeout)实例方法设置超时时长。

    3. 多线程的必要性

      如果使用传统的BufferReaderreadLine()方法,那么在该方法返回成功之前,线程将被阻塞,所以服务端应该为每个不同的客户端连接建立一个线程;同样地,客户端也应该专门为从服务端读取数据建立一个线程。

      特别地:如果考虑聊天室的话,其实是一个全连接的模型:群聊(一对多)、私聊(一对一),需要建立一个根据value映射key的特殊map,因为此map一个key(客户端)的value(输出流)不能与别的重复。

    4. 半关闭

      shutdownInput()isInputShutdown()

      shutdownOutput()isOutputShutdown()

      一旦关闭其中一个流,就无法再次打开

      如果通过获取Socket的输入/输出流,并单独调用IO流的close()方法,则会导致整个Socket被关闭

    5. NIO实现非阻塞式Socket通信

      Selector类,通过其静态的open方法来获取实例,可同时监控多个SelectableChannel的IO状况,是非阻塞式IO的核心。

      有三种SelectionKey集合:

      1. SelectionKey keys():所有注册在Selector上的Channel集合
      2. SelectionKey selectedKeys():可被select()方法获取的需要IO处理的Channel集合
      3. SelectionKey 被取消注册关系的Channel集合

      select系列方法:主要是轮询可读的Channel,是阻塞方法

      SelectableChannel:支持非阻塞IO的Channel对象,可通过实例方法register()注册到Selector上,由SelectionKey表示。同时该类支持阻塞和非阻塞两种模式,可通过SelectableChannel configureBlocking(boolean block)设置,通过boolean isBlocking()来获取模式。但是不同的SelectableChannel支持的操作不尽相同,比如ServerSocketChannel就只代表ServerSocket,只支持OP_ACCEPT操作,可以通过int validOps()获取他支持的所有操作。

      使用ServerSocketChannel来建立服务端:

      ServerSocketChannel server = ServerSocketChannel.open();
      /*SelectableChannel只能通过open方法获得*/
      InetSocketAddress isa = new InetSocketAddress("127.0.0.1", 30000);
      server.bind(isa);
      /*java7以后支持bind方法,否则需要先获取ServerSocket对象,用这个对象去关联地址和端口*/
      
      server.configureBlocking(false);
      server.register(selector, SelectionKey.OP_ACCEPT);
      
    6. AIO实现非阻塞通信

      与同步IO的区别:AIO通过OS完成IO,再将结果返回给程序,而同步IO则是由程序自主实现IO,此时会阻塞线程。这种方式比较复杂。

      为了达到完全的异步操作,可以使用CompletionHandler监听器来监测IO是否完成。

  3. UDP网络编程

    Java使用DatagramSocket类来处理UDP通信。

    构造器:

    1. DatagramSocket():绑定到本机默认IP和某个端口
    2. DatagramSocket(int port)
    3. DatagramSocket(int port, InetAddress laddr)

    发送与接收:

    receive(DatagramPacket p)

    send(DatagramPacket p)

    数据包自主决定目的地:

    DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port):以buf创建数据包对象,从offset开始长度为length的数据包,发送到指定的目的地。(最复杂的构造器)

    setData(byte[] buf)实例方法,可以反复设置其中的数据内容

    有三种实例方法知道DatagramSocket的来源:

    1. InetAddress getAddress()
    2. int getPort()
    3. SocketAddress getSocketAddress()SocketAddress类封装了一个InetAddress对象和一个int值(端口)

    多点广播:MulticastSocket

    joinGroup(InetAddress multicastAddr):加入指定的多点广播地址

    leaveGroup(InetAddress multicastAddr):离开指定的多点广播地址

  4. 代理服务器

    直接使用Proxy类创建URLConnection

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值