Socket网络编程入门

什么是网络编程

什么是网络?java

在计算机领域中,网络是信息传输、接受、共享的虚拟平台。编程

经过它把各个点、面、体的信息联系到一块儿,从而实现这些资源的共享。数组

什么是网络编程?服务器

网络编程从大的方面就是说对信息的发送接收。网络

经过操做相应API调度计算机资源硬件,而且利用管道(网线)进行数据交互的过程。并发

更为具体的涉及:网络模型、套接字、数据包。异步

7层网络模型-OSI

互联网的本质就是一系列的网络协议,这个协议就叫OSI协议(一系列协议),按照功能不一样,分工不一样,人为的分层七层。实际上这个七层是不存在的。没有这七层的概念,只是人为的划分而已。区分出来的目的只是让咱们明白哪一层是干什么用的。socket

每一层都运行不一样的协议。ide

实际上也能够把它划成五层、四层。this

七层划分为:应用层、表示层、会话层、传输层、网络层、数据链路层、物理层

五层划分为:应用层、传输层、网络层、数据链路层、物理层

四层划分为:应用层、传输层、网络层、网络接口层

网络模型

应用层

用户使用的都是应用程序,均工做于应用层,你们均可以开发本身的应用程序,数据多种多样,必须规定好数据的组织形式 。

应用层功能:规定应用程序的数据格式。

好比TCP协议能够为各类各样的程序传递数据,好比Email、WWW、FTP等。那么,必须有不一样协议规定电子邮件、网页、FTP数据的格式,这些应用程序协议就构成了”应用层”。

应用层

表示层

表示层的用途是提供一个可供应用层选择的服务的集合,使得应用层能够根据这些服务功能解释数据的含义。表示层如下各层只关心如何可靠地传输数据,而表示层关心的是所传输数据的表现方式、它的语法和语义。表示服务的例子有统一的数据编码、数据压缩格式和加密技术等。

表示层

会话层

会话层任务是:向两个实体的表示层提供创建和使用链接的方法。将不一样实体之间的表示层的链接称为会话。所以会话层的任务就是组织和协调两个会话进程之间的通讯,并对数据交换进行管理。

会话层

传输层

传输层是通讯子网和资源子网的接口和桥梁,起到承上启下的做用。

该层的主要任务是:向用户提供可靠的端到端的差错和流量控制,保证报文的正确传输。传输层的做用是向高层屏蔽下层数据通讯的细节,即向用户透明地传送报文。

该层常见的协议:TCP/IP中的TCP协议、Novell网络中的SPX协议和微软的NetBIOS/NetBEUI协议。

传输层提供会话层和网络层之间的传输服务,这种服务从会话层得到数据,并在必要时,对数据进行分割。而后,传输层将数据传递到网络层,并确保数据能正确无误地传送到网络层。所以,传输层负责提供两节点之间数据的可靠传送,当两节点的联系肯定以后,传输层则负责监督工做。综上,传输层的主要功能以下:
传输链接管理:提供创建、维护和拆除传输链接的功能。传输层在网络层的基础上为高层提供面向链接面向无链接的两种服务。

传输层

网络层

网络层的做用是在网络与网络相互链接的环境中,将数据从发送端主机发送到接受端主机。

举例:

我在学校教室中,我想找隔壁班的妹子,我通知小弟去告诉她,说有个帅哥找你。而小弟就是网关IP地址就是我所处的教室,MAC地址就是我在教室的某个位置。

网络层

数据链路层、物理层

早期的时候,数据链路层就是来对电信号来作分组的。之前每一个公司都有本身的分组方式,很是的乱,后来造成了统一的标准,即以太网协议Ethernet。

通讯传输其实是经过物理的传输介质实现的。数据链路层的做用就是在这些同构传输介质互连的设备之间进行数据处理。

物理层中,将数据的 0 、1转换为电压和脉冲光传输给物理的传输介质,而相互直连的设备之间使用地址实现传输。这种地址被称为 MAC 地址,也可称为物理地址或硬件地址。采用 MAC 地址信息的首部附加到从网络层转发过来的数据上,将其发送到网络。

网络层与数据链路层都是基于目标地址将数据发送给接收端的,可是网络层负责将整个数据发送给最终目标地址。而数据链路层则只负责发送一个分段内的数据。

OSI七层网络模型 TCP/IP四层概念模型 对应网络协议
应用层(Application) 应用层 HTTP、TFTP, FTP, NFS, WAIS、SMTP
表示层(Presentation) 应用层 Telnet, Rlogin, SNMP, Gopher
会话层(Session) 应用层 SMTP, DNS
传输层(Transport) 传输层 TCP, UDP
网络层(Network) 网络层 IP, ICMP, ARP, RARP, AKP, UUCP
数据链路层(Data Link) 数据链路层 FDDI, Ethernet, Arpanet, PDN, SLIP, PPP
物理层(Physical) 数据链路层 IEEE 802.1A, IEEE 802.2到IEEE 802.11

OSI的封包与解包过程

OSI七层数据协议数据传输时的封包与解包过程

Socket与TCP、UDP

什么是Socket

  • 简单来讲是IP地址与端口的结合协议(RFC 793)
  • 一种地址与端口的结合描述协议。
  • TCP/IP 协议的相关API的总称;是网络API的集合实现。
  • 在计算机通讯领域,Socket 被翻译为“套接字”,它是计算机之间进行通讯的一种约定或一种方式。经过 Socket 这种约定,一台计算机能够接收其余计算机的数据,也能够向其余计算机发送数据。

Socket的做用与组成

  • 在网络传输中用于惟一标识两个端点之间的链接。
  • 端点:包括(IP + Port)
  • 四个要素:客户端地址、客户端端口、服务器地址、服务器端口。

Socket流程

Socket流程

服务器端先初始化Socket,而后与端口绑定(bind),对端口进行监听(listen),调用accept开始阻塞,等待客户端链接。在这时若是有个客户端初始化一个Socket,而后链接服务器(connect),若是链接成功,这时客户端与服务器端的链接就创建了。客户端发送数据请求,服务器端接收请求并处理请求,而后把回应数据发送给客户端,客户端读取数据,最后关闭链接,一次交互结束。

Socket 之 TCP

  • TCP是面向链接的通讯协议
  • 经过三次握手创建链接,通信完成时要拆除链接

    • 第一次握手:客户端发送带有 SYN 标志的链接请求报文段,而后进入 SYN_SEND 状态,等待服务端确认。
    • 第二次握手:服务端接受到客户端的 SYN 报文段后,须要发送 ACK 信息对这个 SYN 报文段进行确认。同时,还要发送本身的 SYN 请求信息。服务端会将上述信息放到一个报文段(SYN+ACK 报文段)中,一并发送给客户端,此时服务端进入 SYN_RECV 状态。
    • 第三次握手:客户端接收到服务端的 SYN+ACK 报文段后,会向服务端发送 ACK 确认报文段,这个报文段发送完毕后,客户端和服务端都进入 ESTABLEISHED 状态,完成 TCP 三次握手。

      TCP 三次握手

  • 因为TCP是面向链接的因此只能用于端到端的通信。

Socket 之 UDP

  • UDP是面向无链接的通信协议。
  • UDP数据包括目标端口号和源端口号信息。
  • 因为通信不须要链接,因此能够实现广播发送,并不局限于端到端。

UDP传输

Client-Server Application

  • TCP/IP 协议中,两个进程间通讯的主要模式为:CS模型。
  • 主要目的:协同网络中的计算机资源、服务模式、进程间数据共享。
  • 常见的:HTTPFTPSMTP

Socket TCP 基础代码实战

客户端代码:

/**
 * @author Jack
 */
public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket();
        // 超时时间
        socket.setSoTimeout(3000);

        // 链接本地,端口2000;超时时间3000ms
        socket.connect(new InetSocketAddress(Inet4Address.getLocalHost(), 2000), 3000);

        System.out.println("已发起服务器链接...");
        System.out.println("客户端信息:" + socket.getLocalAddress() + " P:" + socket.getLocalPort());
        System.out.println("服务器信息:" + socket.getInetAddress() + " P:" + socket.getPort());

        try {
            // 发送接收数据
            todo(socket);
        } catch (Exception e) {
            System.out.println("异常关闭");
        }

        // 释放资源
        socket.close();
        System.out.println("客户端已退出~");

    }

    private static void todo(Socket client) throws IOException {
        // 构建键盘输入流
        InputStream in = System.in;
        BufferedReader input = new BufferedReader(new InputStreamReader(in));

        // 获得Socket输出流,并转换为打印流
        OutputStream outputStream = client.getOutputStream();
        PrintStream socketPrintStream = new PrintStream(outputStream);

        // 获得Socket输入流,并转换为BufferedReader
        InputStream inputStream = client.getInputStream();
        BufferedReader socketBufferedReader = new BufferedReader(new InputStreamReader(inputStream));

        boolean flag = true;
        do {
            // 键盘读取一行
            String str = input.readLine();
            // 发送到服务器
            socketPrintStream.println(str);
            // 从服务器读取一行
            String echo = socketBufferedReader.readLine();
            if ("bye".equalsIgnoreCase(echo)) {
                flag = false;
            } else {
                System.out.println(echo);
            }
        } while (flag);

        // 资源释放
        socketPrintStream.close();
        socketBufferedReader.close();

    }

}

服务端代码:

/**
 * @author jack
 */
public class Server {

    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(2000);

        System.out.println("服务器准备就绪...");
        System.out.println("服务器信息:" + server.getInetAddress() + " P:" + server.getLocalPort());

        // 等待客户端链接
        for (; ; ) {
            // 获得客户端
            Socket client = server.accept();
            // 客户端构建异步线程
            ClientHandler clientHandler = new ClientHandler(client);
            // 启动线程
            clientHandler.start();
        }

    }

    /**
     * 客户端消息处理
     */
    private static class ClientHandler extends Thread {
        private Socket socket;
        private boolean flag = true;

        ClientHandler(Socket socket) {
            this.socket = socket;
        }

        @Override
        public void run() {
            super.run();
            System.out.println("新客户端链接:" + socket.getInetAddress() + " P:" + socket.getPort());
            try (// 获得打印流,用于数据输出;服务器回送数据使用
                 PrintStream socketOutput = new PrintStream(socket.getOutputStream());
                 // 获得输入流,用于接收数据
                 BufferedReader socketInput = new BufferedReader(new InputStreamReader(
                         socket.getInputStream()))) {
                do {
                    // 服务器拿到拿到一条数据
                    String str = socketInput.readLine();
                    if ("bye".equalsIgnoreCase(str)) {
                        flag = false;
                        // 回送
                        socketOutput.println("bye");
                    } else {
                        // 打印到屏幕。并回送数据长度
                        System.out.println(str);
                        socketOutput.println("服务器收到了,你发送的长度为 :" + str.length());
                    }
                } while (flag);
            } catch (Exception e) {
                System.out.println("链接异常断开");
            } finally {
                // 链接关闭
                if (socket != null) {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
            System.out.println("客户端已退出:" + socket.getInetAddress() + " P:" + socket.getPort());
        }
    }

}

运行结果:

服务端

客户端

报文、协议、Mac地址、IP、端口

报文段

  • 报文段是指TCP/IP协议网络传输过程当中,起着路由导航做用。
  • 用于查询各个网络路由网段、IP地址、交换协议等IP数据包。
  • 报文在传输过程当中会不断地封装成分组、包、帧来传输。

传输协议

  • 协议顾名思义,一种规定,约束。
  • 约定大于配置,在网络传输中依然适用;网络的传输流程是很健壮的稳定的,得益于基础的协议构成。
  • 简单来讲: A -> B 的传输数据,B能识别,反之 B -> A 的传输数据 A也能识别,这就是协议。

Mac地址

  • Media Access Control 或者 Medium Access Control。
  • 意译为媒体访问控制,或称为物理地址、硬件地址。
  • 用来定义网络设备位置。
  • 一般被固化在每一个以太网网卡(NIC,Network Interface Card)。MAC(硬件)地址长48位(6字节),采用十六进制格式。
  • 好比:44-45-53-54-00-00 。

    MAC地址及其组成部分

IP地址

  • 互联网协议地址(Internet Protocol Address)。
  • 是分配给网络上使用网际协议的设备的数字标签。
  • 常见的IP地址分为IPv4,IPv6
  • IP地址由32位二进制数组成,常以XXX.XXX.XXX.XXX形式出现,每组XXX表明小于或等于255的10进制数。
  • IP地址分为A、B、C、D、E五大类,其中E类属于特殊保留地址。

IP地址 - IPv4

  • 总数量:4,294,967,296个(即232):42亿个;最终于2011年2月3日用尽。
  • 若是主机号都是1,那么这个地址为直接广播地址。
  • IP地址 "255.255.255.255" 为受限广播地址。

IP地址 - IPv6

  • 总共有128位长,IPv6地址的表达形式,通常采用32个十六进制。
  • 由两个逻辑部分组成:一个64位的网络前缀和一个64位的主机地址,主机地址一般根据物理地址自动生成,叫作EUI-64。
  • 2001:0db8:85a3:0000:1319:8a2e:0370:7344
  • IPv4能够转换为IPv6,但IPv6不必定能转换为IPv4。

端口

  • 若是把IP地址比作一间房子,端口就是出入这间房子的门或者窗户。
  • 外界的信息飞到不一样窗户也就是给不一样的人传递信息。
  • 0-49151号端口都是特殊端口。

常见的特殊端口

  • 计算机之间依照互联网传输层 TCP/IP 协议的协议通讯,不一样协议都对应不一样的端口。
  • 49152到65535号端口属于“动态端口”范围,没有端口能够被正式占用。
相关文章
相关标签/搜索