Socket详解

1. 什么是Socket?

套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

2. Socket通信基本原理

Socket 通信是基于TCP/IP 网络层上的一种传送方式,我们通常把TCP和UDP称为传输层。

如上图,在七个层级关系中,我们将的socket属于传输层,其中UDP是一种面向无连接的传输层协议。UDP不关心对端是否真正收到了传送过去的数据。如果需要检查对端是否收到分组数据包,或者对端是否连接到网络,则需要在应用程序中实现。UDP常用在分组数据较少或多播、广播通信以及视频通信等多媒体领域。在这里我们不进行详细讨论,这里主要讲解的是基于TCP/IP协议下的socket通信。 

所谓套接字,实际上是一个通信端点,每个套接字都有一个套接字序号,包括主机的IP地址与一个16位的主机端口号,即形如(主机IP地址:端口号)。例如,如果IP地址是210.37.145.1,而端口号是23,那么得到套接字就是(210.37.145.1:23)。

套接字可以看成是两个网络应用程序进行通信时,各自通信连接中的一个端点。通信时,其中的一个网络应用程序将要传输的一段信息写入它所在主机的Socket中,该Socket通过网络接口卡的传输介质将这段信息发送给另一台主机的Socket中,使这段信息能传送到其他程序中。因此,两个应用程序之间的数据传输要通过套接字来完成。

在网络应用程序设计时,由于TCP/IP的核心内容被封装在操作系统中,如果应用程序要使用TCP/IP,可以通过系统提供的TCP/IP的编程接口来实现。在Java环境下,网络应用程序编程接口称作Java Socket。为了支持用户开发面向应用的通信程序,大部分系统都提供了一组基于TCP或者UDP的应用程序编程接口(API),该接口通常以一组函数的形式出现,也称为套接字

Socket 调用流程:

3. Socket 整体结构 

public class Socket implements java.io.Closeable {
    /**
     * Various states of this socket.
     */
    // 套接字状态
    // 套接字的状态变更都是有对应操作方法的,比如套接字新建(createImpl 方法)后,状态就会更改成 created = true,连接(connect)之后,状态更改成 connected = true 等等。
    private boolean created = false;        // 已创建
    private boolean bound = false;          // 已绑定
    private boolean connected = false;      // 已连接
    private boolean closed = false;         // 已关闭
    private Object closeLock = new Object();// 关闭锁
    private boolean shutIn = false;         // 读是否关闭
    private boolean shutOut = false;        // 写是否关闭

    /**
     * The implementation of this Socket.
     */
    // 套接字实现
    // 包含套接字create,connect,bind,listen,accept,getInputStream
    // getOutputStream,close,shutdownInput,shutdownOutput等方法
    SocketImpl impl;

    
}

3.1 套接字构造器:

Socket 的构造器比较多,可以分成两大类:

1. 指定代理类型(Proxy)创建套节点,一共有三种类型为:DIRECT(直连)、HTTP(HTTP、FTP 高级协议的代理)、SOCKS(SOCKS 代理),三种不同的代码方式对应的 SocketImpl 不同,分别是:PlainSocketImpl、HttpConnectSocketImpl、SocksSocketImpl,除了类型之外 Proxy 还指定了地址和端口;

public Socket(Proxy proxy) {
        // Create a copy of Proxy as a security measure
        if (proxy == null) {
            throw new IllegalArgumentException("Invalid Proxy");
        }
        Proxy p = proxy == Proxy.NO_PROXY ? Proxy.NO_PROXY
                                          : sun.net.ApplicationProxy.create(proxy);
        Proxy.Type type = p.type();
        if (type == Proxy.Type.SOCKS || type == Proxy.Type.HTTP) {
            SecurityManager security = System.getSecurityManager();
            InetSocketAddress epoint = (InetSocketAddress) p.address();
            if (epoint.getAddress() != null) {
                checkAddress (epoint.getAddress(), "Socket");
            }
            if (security != null) {
                if (epoint.isUnresolved())
                    epoint = new InetSocketAddress(epoint.getHostName(), epoint.getPort());
                if (epoint.isUnresolved())
                    security.checkConnect(epoint.getHostName(), epoint.getPort());
                else
                    security.checkConnect(epoint.getAddress().getHostAddress(),
                                  epoint.getPort());
            }
            // 对应的实现为:PlainSocketImpl、HttpConnectSocketImpl、SocksSocketImpl
            impl = type == Proxy.Type.SOCKS ? new SocksSocketImpl(p
  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值