TCP/IP、UDP、HTTP、Socket到底是什么

来源:互联网 发布:unity3d免费版限制 编辑:程序博客网 时间:2024/06/05 07:14

我们经常会遇到被问TCP/IP、UDP、HTTP、Socket这几个关键词,他们之间到底有什么联系呢?我们来看一下

实际上,传输层的TCP是基于网络层的IP协议的,而应用层的HTTP协议又是基于传输层的TCP协议的,而Socket本身不算是协议,它只是提供了一个针对TCP或者UDP编程的接口。他们之间并没有什么严格的可比性。


温馨提示:以下名词解释是官方介绍,我会给大家总结的,不想看的直接跳到“白话”段。

名词解释

    TCP/IP

   (Transmission Control Protocol/Internet Protocol)传输控制协议/因特网互联协议,又名网络通讯协议,是Internet最基本的协议,网络层的IP协议和传输层的TCP协议组成。TCP负责发现传输的问题,一有问题就发出信号,要求重新传输,直到所有数据安全正确地传输到目的地。而IP是给因特网的每一台联网设备规定一个地址。

        IP

        IP层接收由更低层(网络接口层例如以太网设备驱动程序)发来的数据包,并把该数据包发送到更高层---TCP或UDP层;相反,IP层也把从            TCP或UDP层接收来的数据包传送到更低层。IP数据包是不可靠的,因为IP并没有做任何事情来确认数据包是否按顺序发送的或者有没有被破坏,        IP数据包中含有发送它的主机的地址(源地址)和接收它的主机的地址(目的地址)。

        TCP

         是面向连接的通信协议,通过三次握手建立连接,通讯完成时要拆除连接,由于TCP是面向连接的所以只能用于端到端的通讯。TCP提供的是        一种可靠的数据流服务,采用“带重传的肯定确认”技术来实现传输的可靠性。TCP还采用一种称为“滑动窗口”的方式进行流量控制,所谓窗口实际          表示接收能力,用以限制发送方的发送速度。如果IP数据包中有已经封好的TCP数据包,那么IP将把它们向‘上’传送到TCP层。TCP将包排序并进          行        错误检查,同时实现虚电路间的连接。TCP数据包中包括序号和确认,所以未按照顺序收到的包可以被排序,而损坏的包可以被重传。              TCP将它的信息送到更高层的应用程序,例如Telnet的服务程序和客户程序。应用程序轮流将信息送回TCP层,TCP层便将它们向下传送到IP层,        设备驱动程序和物理介质,最后到接收方。

    UDP

    (User Datagram Protocol用户数据报协议,UDP是面向无连接的传输层通讯协议,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播发送。UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。


    UDPTCP位于同一层,但它不管数据包的顺序、错误或重发。因此,UDP不被应用于那些使用虚电路的面向连接的服务,UDP主要用于那些面向查询---应答的服务,例如NFS。相对于FTP或Telnet,这些服务需要交换的信息量较小。使用UDP的服务包括NTP(网络时间协议)和DNS(DNS也使用TCP)。

    欺骗UDP包比欺骗TCP包更容易,因为UDP没有建立初始化连接(也可以称为握手)(因为在两个系统间没有虚电路),也就是说,与UDP相关的服务面临着更大的危险。

    HTTP

   (HyperText Transfer Protocol)超文本传输协议,HTTP是一个客户端服务器端请求和应答的标准(TCP)。是WEB网的基础,也是手机联网的常用协议之一。

    Socket

    网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求。是TCP/IP的API。

白话

至于上面的概念我才不会看,看了也记不住,还是理解了比较好

  • TCP:
TCP是传输控制协议,他属于传输层,是一种面向有连接的可靠的(PS:也不一定可靠,相对UDP)、基于字节流的有序的IP环境下的数据传输协议。它效率较UDP低

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连接的请求,断开过程需要经过“四次握手”


使用场景:
FTP、HTTP等(对文件完整性、准确性要求高的),发送或接收邮件(POPIMAP SMTP 对数据准确性要求高,非紧急应用),远程登录(TELNET SSH 对数据准确性有一定要求,有连接的概念)

  • UDP:
用户数据报协议,属于传输层提供面向事务的简单不可靠信息传送服务,是一种面向无连接不可靠基于报文的无序的IP环境下网络传输协议。也以为他的特性表现出比TCP速度快效率高的优点。

使用场景:

对于那些对数据要求质量不高,只要求数据传输速度快的都行,比如:即时通信(QQ聊天 对数据准确性和丢包要求比较低,但速度必须快),在线视频(RTSP 速度一定要快,保证视频连续,但是偶尔花了一个图像帧,人们还是能接受的),网络语音电话(VoIP 语音数据包一般比较小,需要高速发送,偶尔断音或串音也没有问题)等等。


有一个例子方便理解:


以上两者相比较HTTP具有:数据传输量小,可以加密安全性好,适用于C/S模式。

  • IP
是网络层的一个网络协议,属于网络层,能使连接到网上的所有计算机网络实现相互通信的一套规则,规定了计算机在因特网上进行通信时应当遵守的规则。
IP地址(了解)
IP地址分为五类,A类保留给政府机构,B类分配给中等规模的公司,C类分配给任何需要的人,D类用于组播,E类用于实验,各类可容纳的地址数目不同。
A、B、C三类IP地址的特征:当将IP地址写成二进制形式时,A类地址的第一位总是0,B类地址的前两位总是10,C类地址的前三位总是110。
A类地址
(1)A类地址第1字节为网络地址,其它3个字节为主机地址。它的第1个字节的第一位固定为0.
(2)A类地址网络号范围:1.0.0.0---126.0.0.0
(3)A类地址中的私有地址和保留地址:
① 10.X.X.X是私有地址(所谓的私有地址就是在互联网上不使用,而被用在局域网络中的地址)。
范围(10.0.0.0---10.255.255.255)
② 127.X.X.X是保留地址,用做循环测试用的。
B类地址
(1) B类地址第1字节和第2字节为网络地址,其它2个字节为主机地址。它的第1个字节的前两位固定为10.
(2) B类地址网络号范围:128.0.0.0---191.255.0.0。
(3) B类地址的私有地址和保留地址
① 172.16.0.0---172.31.255.255是私有地址
② 169.254.X.X是保留地址。如果你的IP地址是自动获取IP地址,而你在网络上又没有找到可用的DHCP服务器。就会得到其中一个IP。
191.255.255.255是广播地址,不能分配。
C类地址
(1)C类地址第1字节、第2字节和第3个字节为网络地址,第4个字节为主机地址。另外第1个字节的前三位固定为110。
(2)C类地址网络号范围:192.0.0.0---223.255.255.0。
(3) C类地址中的私有地址:
192.168.X.X是私有地址。(192.168.0.0---192.168.255.255)
D类地址
(1) D类地址不分网络地址和主机地址,它的第1个字节的前四位固定为1110。
(2) D类地址范围:224.0.0.0---239.255.255.255
E类地址
(1) E类地址不分网络地址和主机地址,它的第1个字节的前五位固定为11110。
(2) E类地址范围:240.0.0.0---255.255.255.254
IP地址如果只使用ABCDE类来划分,会造成大量的浪费:一个有500台主机的网络,无法使用C类地址。但如果使用一个B类地址,6万多个主机地址只有500个被使用,造成IP地址的大量浪费。因此,IP地址还支持VLSM技术,可以在ABC类网络的基础上,进一步划分子网。
无类地址
除ABCDE以外的IP地址段划分方式,如:192.168.1.0 255.255.255.252等分成C段划分的地址

  • HTTP
超文本传输协议,属于应用层,HTTP协议是建立在TCP协议之上的一种应用,HTTP连接最显著的特点是客户端发送的每次请求都需要服务器回送响应,在请求结束后,会主动释放连接。从建立连接到关闭连接的过程称为“一次连接”。封装了 HTTP 文本信息,然后使用TCP/IP做传输层协议将它发到网络上。也就是通过这种协议封装(也可以自定义),WEB就能够认识并解析操作,主要解决如何包装数据。可以传输数据量大的信息、容错性强能够实时交互,但是也因为此,传输速度慢服务器压力大安全性差
主要方法
Get、Post
使用场景
公司OA服务,互联网服务。
  • Socket
就是套接字,socket是对TCP/IP协议的封装和应用。Socket的出现只是使得程序员更方便地使用TCP/IP协议栈而已,是对TCP/IP协议的抽象,Socket本身并不是协议,而是一个调用接口(API),比如create、 listen、connect、accept、send、read和write等等。通过Socket,我们才能使用TCP/IP协议。

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

使用场景
网络游戏,银行交互,支付。

Android中使用范例

HTTP

package com.lzy.aidldemo;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import android.os.AsyncTask;import android.os.Bundle;import android.support.v7.app.AppCompatActivity;import android.view.View;import android.widget.ImageView;import java.io.IOException;import java.io.InputStream;import java.net.HttpURLConnection;import java.net.MalformedURLException;import java.net.ProtocolException;import java.net.URL;public class MainActivity extends AppCompatActivity {    private ImageView mImageView;    private final String URL = "http://img2.imgtn.bdimg.com/it/u=1744644003,881536991&fm=21&gp=0.jpg";    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mImageView = (ImageView) findViewById(R.id.image);        new SocketServer(8000).beginListen();    }    public void http(View view){        new MyTask().execute(URL);    }    public void socket(View view){//        new SocketClient("127.0.0.1", 8000).sendMsg("hy");    }    private class MyTask extends AsyncTask<String, Integer, Bitmap> {        @Override        protected Bitmap doInBackground(String... params) {            InputStream is = null;            Bitmap bitmap = null;            HttpURLConnection conn = null;            try {                java.net.URL url = new URL(params[0]);                conn = (HttpURLConnection) url.openConnection();                conn.setDoInput(true);                /////                conn.connect();                is = conn.getInputStream();                bitmap = BitmapFactory.decodeStream(is);                is.close();            } catch (MalformedURLException e) {                e.printStackTrace();            } catch (ProtocolException e) {                e.printStackTrace();            } catch (IOException e) {                e.printStackTrace();            } finally {                conn.disconnect();            }            return bitmap;        }        @Override        protected void onPostExecute(Bitmap bitmap) {            mImageView.setImageBitmap(bitmap);        }    }}
由于Android2.3之后Google建议使用HttpURLConnection,而不是HttpClient所以范例使用了这个。

Socket

服务端:
package com.lzy.aidldemo;import java.io.*;import java.net.*;public class SocketServer {    ServerSocket sever;    public SocketServer(int port){        try{            sever = new ServerSocket(port);        }catch(IOException e){            e.printStackTrace();        }    }    public void beginListen(){        while(true){            try{                final Socket socket = sever.accept();                new Thread(new Runnable(){                    public void run(){                        BufferedReader in;                        try{                            in = new BufferedReader(new InputStreamReader(socket.getInputStream(),"UTF-8"));                            PrintWriter out = new PrintWriter(socket.getOutputStream());                            while (!socket.isClosed()){                                String str;                                str = in.readLine();                                out.println("Hello!world!! " + str);                                out.flush();                                if (str == null || str.equals("end"))                                    break;                                System.out.println(str);                            }                            socket.close();                        }catch(IOException e){                            e.printStackTrace();                        }                    }                }).start();            }catch(IOException e){                e.printStackTrace();            }        }    }}
客户端:
package com.lzy.aidldemo;import java.io.*;import java.net.*;public class SocketClient {    static Socket client;    public SocketClient(String site, int port){        try{            client = new Socket(site,port);            System.out.println("Client is created! site:"+site+" port:"+port);        }catch (UnknownHostException e){            e.printStackTrace();        }catch (IOException e){            e.printStackTrace();        }    }    public String sendMsg(String msg){        try{            BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));            PrintWriter out = new PrintWriter(client.getOutputStream());            out.println(msg);            out.flush();            return in.readLine();        }catch(IOException e){            e.printStackTrace();        }        return "";    }    public void closeSocket(){        try{            client.close();        }catch(IOException e){            e.printStackTrace();        }    }}

先运行服务端再运行客户端服务端就能收到客户端的信息了。

0 0
原创粉丝点击