赞
踩
目录
tcp/ip是一个网络通信模型,以及整个网络传输协议家族,是互联网的基础通信架构。他被成为是tcp/ip协议族,简称tcp/ip。该协议家族的两个最核心的通信协议是TCP和IP协议。
TCP(传输控制协议):主要用于规范数据怎么建立连接传输,怎么传输数据,
TCP
TCP是面向通信的协议,会建通过三次握手来建立连接,然后在传递数据,并且断开连接需要四次握手。并且在数据传输的时候会通过底层复杂的算法来对数据进行确认,确认机制,重传机制,拥塞机制,等保证数据的时序性和完整性。不容易丢失数据,只能用于端到端的通信。什么时候应该使用TCP: 当对网络通讯质量有要求的时候,比如:整个数据要准确无误的传递给对方,这往往用于一些要求可靠的应用,比如HTTP、HTTPS、FTP等传输文件的协议,POP、SMTP等邮件传输的协议,均使用了TCP协议。但是开销大
UDP
UDP是面向无连接的通讯协议,硬件之间不需要创建连接,UDP数据包括目的端口号和源端口号信息,由于通讯不需要连接,所以可以实现广播(广播的形式在局域网中大家都能都听到)发送,能够一对多,。UDP通讯时不需要接收方确认,属于不可靠的传输,可能会出现丢包现象,实际应用中要求程序员编程验证。UDP只用于特殊服务采用该协议。例如例如IP电话,视频会议
IP(网际协议):主要用于规范通信双方处于网络的地址,地址规范化
IP层接受更底层网络接口层(网络接口层例如以太网设备驱动程序)发送的数据包,并且将数据发送给更高层的TCP或者UDP,相反IP层也会从TCP或者UDP接受数据传送到更底层,每一台设备在互联网上的IP都是唯一的。
UDP和TCP对比
1、TCP面向连接(如打电话要先拨号建立连接);UDP是无连接的,即发送数据之前不需要建立连接
2、TCP提供可靠的服务。也就是说,通过TCP连接传送的数据,无差错,不丢失,不重复,且按序到达;UDP尽最大努力交付,即不保证可靠交付 Tcp通过校验和,重传控制,序号标识,滑动窗口、确认应答实现可靠传输。如丢包时的重发控制,还可以对次序乱掉的分包进行顺序控制。
3、UDP具有较好的实时性,工作效率比TCP高,适用于对高速传输和实时性有较高的通信或广播通信。
4.每一条TCP连接只能是点到点的;UDP支持一对一,一对多,多对一和多对多的交互通信
5、TCP对系统资源要求较多,UDP对系统资源要求较少。
我们在用Socket编程时,UDP协议要求包小于64K。TCP没有限定;虽然在传输层,TCP不会对数据长度作出限制, 由于TCP是数据流协议,因此不存在包大小的限制(暂不考虑缓冲区的大小),这是指在用send函数时,数据长度参数不受限制。而实际上,所指定的这段数据并不一定会一次性发送出去,如果这段数据比较长,会被分段发送,如果比较短,可能会等待和下一次数据一起发送。UDP协议要求包小于64K。
但是在网络层(IP) 中都会对数据超过1500字节做出拆分,分批发送。TCP保证顺序,但是UDP不保证顺序。
数据链路层以太网协议下TCP和IP的数据长度:
UDP 包的大小就应该是 1500 - IP头(20) - UDP头(8) = 1472(Bytes)
TCP 包的大小就应该是 1500 - IP头(20) - TCP头(20) = 1460 (Bytes)
在上一章节中,我们理解了OSI(open system internation)七层网络模型,那么做在tcp/ip通信模型中会将整个网络划分为5层,以此对应OSI,图例如下。
我们知道了TCP(传输控制协议)是实现端对端的通信,需要建立三次握手连接,来保证端到端的通道创建。
TCP/IP协议的详细信息参看《TCP/IP协议详解》三卷本。下面是TCP报文格式图:
上图中有几个字段需要重点介绍下:
(1)序号:Seq序号,占32位,用来标识从TCP源端向目的端发送的字节流,发起方发送数据时对此进行标记。
(2)确认序号:Ack序号,占32位,只有ACK标志位为1时,确认序号字段才有效,Ack=Seq+1。
(3)标志位:共6个,即URG、ACK、PSH、RST、SYN、FIN等,具体含义如下:
(A)URG:紧急指针(urgent pointer)有效。
(B)ACK:确认序号有效。
(C)PSH:接收方应该尽快将这个报文交给应用层。
(D)RST:重置连接。
(E)SYN:发起一个新连接。
(F)FIN:释放一个连接。
需要注意的是:
(A)不要将确认序号Ack与标志位中的ACK搞混了。
(B)确认方Ack=发起方Req+1,两端配对。
所谓三次握手(Three-Way Handshake)即建立TCP连接,就是指建立一个TCP连接时,需要客户端和服务端总共发送3个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发,整个流程如下图所示:
(1)第一次握手:Client将标志位SYN置为1,随机产生一个值seq=J,并将该数据包发送给Server,Client进入SYN_SENT状态,等待Server确认。
(2)第二次握手:Server收到数据包后由标志位SYN=1知道Client请求建立连接,Server将标志位SYN和ACK都置为1,ack=J+1,随机产生一个值seq=K,并将该数据包发送给Client以确认连接请求,Server进入SYN_RCVD状态。
(3)第三次握手:Client收到确认后,检查ack是否为J+1,ACK是否为1,如果正确则将标志位ACK置为1,ack=K+1,并将该数据包发送给Server,Server检查ack是否为K+1,ACK是否为1,如果正确则连接建立成功,Client和Server进入ESTABLISHED状态,完成三次握手,随后Client与Server之间可以开始传输数据了。
三次握手耳熟能详,所谓四次挥手(Four-Way Wavehand)即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发,整个流程如下图所示:
由于TCP连接时全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭,上图描述的即是如此。
(1)第一次挥手:Client发送一个FIN,用来关闭Client到Server的数据传送,Client进入FIN_WAIT_1状态。
(2)第二次挥手:Server收到FIN后,发送一个ACK给Client,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),Server进入CLOSE_WAIT状态。
(3)第三次挥手:Server发送一个FIN,用来关闭Server到Client的数据传送,Server进入LAST_ACK状态。
(4)第四次挥手:Client收到FIN后,Client进入TIME_WAIT状态,接着发送一个ACK给Server,确认序号为收到序号+1,Server进入CLOSED状态,完成四次挥手。
由于TCP连接是全双工的的,因此,每个方向都必须要单独进行关闭简单来说。张三对说小红要分手(第一次),小红会把张三的东西还给张三(第二次),小红说可以跟张三分手(第三次),张三分手并把正式分手信息告诉小红(第四次)。
socekt是网络编程接口:socket被称作套接字,前边我们讲了TCP/IP模型,里边重要的协议TCP和UDP,那么TCP/IP也需要提供出来可以给程序员做网络开发的编程接口,这就是socket编程接口,http是轿车,提供了封装和显示数据的具体实现形式;socket就是发动机,提供网络通信的能力。
service端代码如下:
- package com.thit.socket;
-
- import java.io.InputStream;
- import java.net.ServerSocket;
- import java.net.Socket;
-
- public class Service1 {
- //代码为固定套路
- public static void main(String[] args) throws Exception {
- //补充:端口范围0-65535,0-1023为系统占用端口
- //服务端指定端口
- int port=65531;
- ServerSocket service=new ServerSocket(port);
- //service将一直等待连接的到来
- System.out.println("-----service启动了!---------");
-
- Socket socket=service.accept();
- InputStream inputStream=socket.getInputStream();
- byte[] bytes=new byte[1024];
- int len;
- StringBuilder sBuilder=new StringBuilder();
- while ((len=inputStream.read(bytes))!=-1) {
- sBuilder.append(new String(bytes, 0, len, "UTF-8"));
- }
- System.out.println("service接受的数据是:"+sBuilder);
- inputStream.close();
- socket.close();
- service.close();
- }
-
- }
客户端代码如下:
- package com.thit.socket;
-
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.Socket;
-
- public class Client1 {
-
- public static void main(String[] args) throws Exception, IOException {
- // TODO Auto-generated method stub
- String host="127.0.0.1";
- int port=65531;
- //创建端到端的连接
- Socket socket=new Socket(host, port);
- OutputStream outputStream=socket.getOutputStream();
- String msg="hello word!";
- outputStream.write(msg.getBytes("UTF-8"));
- outputStream.close();
- socket.close();
- }
-
- }
然后启动服务端和客户端,得到结果如下:
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。