初识http、https、TCP/IP、Socket网络通信

来源:互联网 发布:为什么dota2知乎 编辑:程序博客网 时间:2024/06/05 04:59
网络由下往上分为: 
物理层–                     
数据链路层–
网络层–                       IP协议
传输层–                       TCP协议
会话层–
表示层和应用层–           HTTP协议
 

一、TCP/IP连接

  手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接。TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上。
建立起一个TCP连接需要经过“三次握手”:
 
第一次握手
客户端发送syn包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
 
第二次握手
服务器收到syn包,必须确认客户的SYN(ack=j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
 
第三次握手
客户端收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack=k+1),此包发送完毕,客户端和服务器进入ESTABLISHED状态,完成三次握手。
握手过程中传送的包里不包含数据,三次握手完毕后,客户端与服务器才正式开始传送数据。理想状态下,TCP连接一旦建立,在通信双方中的任何一方主动关闭连接之前,TCP 连接都将被一直保持下去。断开连接时服务器和客户端均可以主动发起断开TCP连接的请求,断开过程需要经过“四次握手”(过程就不细写了,就是服务器和客户端交互,最终确定断开).

二、https 与 http

  1. HTTPS
    HTTPS(全称:Hyper Text Transfer Protocol over Secure Socket Layer),是以安全为目标的HTTP通道,简单讲是HTTP的安全版。即HTTP下加入SSL层,HTTPS的安全基础是SSL,因此加密的详细内容就需要SSL。
    https:URL 表明它使用了HTTP,但HTTPS存在不同于HTTP的默认端口及一个加密/身份验证层(在HTTP与TCP之间)。
    HTTPS使用端口443,而不是像HTTP那样适用端口80来和TCP/IP 进行通信。SSL使用40位关键字作为RC4流加密算法,这对于商业信息的加密是合适的。HTTPS和SSL支持使用X.509数字认证,如果需要的话用户可以确认发送者是谁。
    主要作用分为两种:

    • 一种是建立一个信息安全通道,来保证数据传输的安全。
    • 另一种就是确认网站的真实性,凡是使用https的网站,都可以通过点击浏览器地址栏的锁头标志来查看网站认证之后的真实信息。也可以通过CA 机构颁发的安全签章来查询。
  2. HTTP
    超文本协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络协议。Http定义了浏览器(即万维网客户进程)怎样向万维网服务器请求万维网文档,以及服务器怎么把文档传给浏览器。Http是万维网可靠的交换文件(包括文本、图像、声音、以及视频等)的基础。
    HTTP是一个属于应用层的面向对象的协议,由于其简捷、快速的方式,适用于分布式超媒体信息系统。它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展。
    HTTP协议的主要特点:

    • 支持C/S(客户/服务器)模式。
    • 简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST,每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
    • 灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
    • 无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
    • 无状态:HTTP协议是无状态协议,无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
  3. HTTPS 和 HTTP 的区别
    超文本传输协议HTTP协议被用于在Web浏览器和服务器之间传递信息。

    • HTTP协议以明文方式发送内容,不提供任何方式的数据加密,如果攻击者截取了Web浏览器和网站服务器之间的传输报文,就可以直接读懂其中的信息,因此HTTP协议不适合传输一些敏感信息,比如信用卡号、密码等。
    • 为了解决HTTP协议的这一缺陷,需要使用另一种协议:安全套接字层超文本传输协议HTTPS。为了数据传输的安全,HTTPS在HTTP的基础上加入了SSL协议,SSL依靠证书来验证服务器的身份,并为浏览器和服务器之间的通信加密。

    HTTPS和HTTP的区别:

    • https 用的 443 端口, http 用的 80 端口
    • 采用 https 的服务器必须从CA(Certificate Authority)申请一个用于证明服务器用途类型的证书。
    • http是超文本传输协议,信息是明文传输,https 则是具有安全性的ssl加密传输协议。
    • http的连接很简单,是无状态的;HTTPS协议是由SSL+HTTP协议构建的可进行加密传输、身份认证的网络协议,比http协议安全。

三、TCP/IP、Socket网络通信

  1. 网络间的进程通信与Socket
    TCP/IP协议族中网络层的IP地址可以唯一标识网络中的主机,而传输层的协议+端口可以唯一标识主机中的应用程序(进程)。这样利用这三元组就可以标识网络的进程了,网络中的进程通信就可以利用这个标志与其它进程进行交互。
    Socket通常也称作”套接字“,用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。就目前而言,几乎所有的应用程序都是采用Socket来实现网络进程之间的通信。
    Socket所支持的协议种类也不光TCP/IP一种,因此两者之间是没有必然联系的。在Java环境下,Socket编程主要是指基于TCP/IP协议的网络编程。
  2. TCP、UDP
    TCP是Tranfer Control Protocol的简称,是一种面向连接的保证可靠传输的协议。通过TCP协议传输,得到的是一个顺序的无差错的数据流。发送方和接收方的成对的两个socket之间必须建立连接,需要连接时间,以便在TCP协议的基础上进行通信。
    优缺点和应用场景:
    (1)可靠稳定,传递数据前,会有三次握手建立连接,面向有连接。
    (2)传递数据时,有确认、窗口(流量控制)、重传、拥塞控制。确认机制保证接收端每收到一个正确包都会回应给发送端,超时或者数据包不完整的话发送端会重传。
    缺点:
    (1)整体来说传输慢,效率低,占用系统资源高。
    (2)传递数据前,建立连接需要耗时,传递数据时,确认、重传、拥塞等会消耗大量时间以及CPU和内存等硬件资源。
    (3)因为有确认机制、三次握手等机制,容易被人利用,实现DOS 、DDOS攻击。
    当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议。

    UDP是User Datagram Protocol的简称,是一种无连接的协议,每个数据报都是一个独立的信息,包括完整的源地址或目的地址,因此无需建立发送方和接收方的连接,它在网络上以任何可能的路径传往目的地,因此能否到达目的地,到达目的地的时间以及内容的正确性、次序性都是不能被保证的。而且被传输数据报必须限定在64k以内。

  3. Socket通信

    1. 利用Socket建立连接的过程
      套接字之间的连接过程分为三个步骤:服务器监听,客户端请求,连接确认。
      (1)服务器监听:服务器端套接字处于等待连接的状态,实时监控网络状态,等待客户端的连接请求。
      (2)客户端请求:指客户端的套接字提出连接请求,要连接的目标是服务器端的套接字。为此,客户端的套接字必须首先描述它要连接的服务器的套接字,指出服务器端套接字的地址和端口号,然后就向服务器端套接字提出连接请求。
      (3)连接确认:当服务器端套接字监听到或者说接收到客户端套接字的连接请求时,就响应客户端套接字的请求,建立一个新的线程,把服务器端套接字的描述发给客户端,一旦客户端确认了此描述,双方就正式建立连接。而服务器端套接字继续处于监听状态,继续接收其他客户端套接字的连接请求。

    2. Socket的Java实现
      服务端:

import java.io.DataInputStream;          import java.io.DataOutputStream;          import java.io.IOException;          import java.net.ServerSocket;          import java.net.Socket;          public class SocketManager {            public static void main(String[] args) {            SocketManager manager = new SocketManager();            manager.doListen();             }            public void doListen() {            ServerSocket server;            try {                server = new ServerSocket(9991);                while (true) {                    Socket client = server.accept();                    new Thread(new SSocket(client)).start();                }            } catch (IOException e) {                e.printStackTrace();            }           }          //服务器进程           class SSocket implements Runnable {            Socket client;            public SSocket(Socket client) {                this.client = client;            }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
        public void run() {            DataInputStream input;            DataOutputStream output;            try {                input = new DataInputStream(client.getInputStream());                output = new DataOutputStream(client.getOutputStream());                String listMsg = input.readUTF();                output.writeUTF("Send : " + listMsg + " \r\n HelloVillage...");                System.out.println("Recive: " + listMsg);                listMsg = input.readUTF();                output.writeUTF("Send Second: " + listMsg + " \r\n HelloVillage...");                System.out.println("Recive Second: " + listMsg);            } catch (IOException e) {                e.printStackTrace();            }          }        }      }

客户端:

  import java.io.DataInputStream;          import java.io.DataOutputStream;          import java.io.IOException;          import java.io.OutputStream;          import java.net.Socket;          import java.net.UnknownHostException;           public class SocketClient {          public static void main(String[] args) {            Socket socket = null;            try {                socket = new Socket("127.0.0.1", 9991);                //向服务器端第一次发送字符串                 OutputStream netOut = socket.getOutputStream();                DataOutputStream doc = new DataOutputStream(netOut);                DataInputStream in = new DataInputStream(socket.getInputStream());                //向服务器端第二次发送字符串                 doc.writeUTF("list");                String res = in.readUTF();                System.out.println(res);                doc.writeUTF("bye");                res = in.readUTF();                System.out.println(res);                doc.close();                in.close();            } catch (UnknownHostException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            } {                if (socket != null) {                    try {                        socket.close();                    } catch (IOException e) {                    }                }             }           }          }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
0 0