网络编程之socket

数据在网络传输过程中,因为数据报长度有限,所以数据会被拆分成多个包,在目的地拆包重新组装,这个过程可能会出现丢包,包乱序,包错误等传输问题,Socket封装了这些过程,将网络抽象为数据流,程序员利用Socket编程屏蔽了网络底层的细节

利用Socket实现主机之间的通信通常需要进行以下的操作
1.连接远程机器 2.发送数据 3.接收数据 4.关闭连接

如果是服务端还需要进行以下操作
5.绑定端口 6.监听入站数据 7.在绑定端口上接收来自远程机器的连接

例子

在这个例子中构造一个Socket,与time.nist.gov通信获取时间(美国时间)

try (Socket socket = new Socket("time.nist.gov", 13)) {
    InputStream in = socket.getInputStream();
    BufferedReader reader = new BufferedReader(new InputStreamReader(in, "ASCII"));
    //如果socket在15毫秒内没有响应会抛出ConnectExceiont
    //如果一个有问题的服务器接收了请求但是没有主动关闭连接,该参数并不会起作用
    socket.setSoTimeout(15000);
    StringBuilder sb = new StringBuilder();
    String line;
    while ((line = reader.readLine()) != null) {
        sb.append(line);
        sb.append("\n");
    }
    System.out.println(sb.toString());
} catch (IOException e) {
    throw new RuntimeException(e);
}

在某些情况下,我们发完请求数据并不在使用输出流的时候我们可以选择关闭输出(输入)流

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

这种选择性的关闭流我们称之为半关闭socket,半关闭socket只会释放socket流,并不会关闭socket,如果读取一个已经关闭的InputStream会返回-1,写入一个已经关闭的OutputStream会抛出IO异常

address

在Socket编程的时候常会遇到两个Address类,一个是InetAddress,另一个是InetSocketAddress,这两个address的区别在于
InetAddress是Java对IP地址的封装,表示互联网的IP地址
InetAddress对象的获取只能通过静态方法,比如根据主机名获取主机的IP地址封装对象

InetAddress address = InetAddress.getByName("www.baidu.com");

InetSocketAddress是SocketAddress的实现子类也是SocketAddress的唯一子类与InetAddress相比多了端口号,此类实现IP套接字地址(IP 地址 + 端口号)不依赖任何协议。一半用于Socket编程中

Socket使用InetSocketAddress作为连接参数

final Socket socket = new Socket();
SocketAddress address = new InetSocketAddress("www.fortify.net", 443);
try {
    socket.connect(address);
} catch (IOException e) {
    e.printStackTrace();
}

Proxy代理

在初始化socket的时候可以为socket设置代理,但是设置的代理是应用于系统中所有的socket,也可以为参数传入Proxy.NO_PROXY完全绕过所有的代理服务器而直接连接

SocketAddress proxyAddress = new InetSocketAddress("www.example.com", 1234);
Proxy proxy = new Proxy(Proxy.Type.SOCKS, proxyAddress);
Socket socket = new Socket(proxy);
SocketAddress remote = new InetSocketAddress("www.baidu.com", 443);
socket.connect(remote);

上面设置代理的时候用到了Proxy.Type,Type有三种类型,分别是SOCKS,HTTP,DIRECT,其中SOCKS是java理解的唯一一种底层的代理协议,HTTP协议是应用层协议,以及一个表示无代理连接的DIRECT

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值