精华内容
下载资源
问答
  • TCP数据发送之发送窗口

    千次阅读 2019-02-26 00:07:12
    而滑动窗口的大小受限于发送窗口和拥塞窗口,拥塞窗口由拥塞控制算法的代表,而发送窗口是流量控制算法的代表,这篇笔记记录了发送窗口相关的内容,包括发送窗口的初始化、更新、以及它是如何影响数据发送过程的。...

    TCP的发送过程由滑动窗口控制,而滑动窗口的大小受限于发送窗口和拥塞窗口,拥塞窗口由拥塞控制算法的代表,而发送窗口是流量控制算法的代表,这篇笔记记录了发送窗口相关的内容,包括发送窗口的初始化、更新、以及它是如何影响数据发送过程的。

    1. 概述

    TCP的发送窗口可以用下图表示:
    在这里插入图片描述

    如图所示,TCB中有三个成员和发送窗口强相关。

    struct tcp_sock {
    ...
    	//下一个要发送的序号,即序号等于snd_nxt的数据还没有发送
    	u32	snd_nxt;	/* Next sequence we send		*/
    	//已经发送,但是还没有被确认的最小序号,注意序号等于snd_una的数据已经发送,
    	//最想收到的确认号要大于snd_una。但是有一个特殊情况,如果发送的所有数据都
    	//已经被确认,那么snd_una将等于下一个要发送的数据,即snd_una代表的数据还
    	//没有发送,见下面tcp_ack()更新snd_una就可以理解这一点了
    	u32	snd_una;	/* First byte we want an ack for	*/
    	//发送窗口大小,以字节为单位,来源于输入段首部的窗口字段,即对端接收缓冲区的剩余大小
    	u32	snd_wnd;	/* The window we expect to receive	*/
    	//记录到目前为止对端通告过的窗口的最大值,可以代表对端接收缓冲区的最大值
    	u32	max_window;	/* Maximal window ever seen from peer	*/
    	//写系统调用一旦成功返回,说明数据一被TCP协议接收,这时就要为每一个数据分配一个序号,
    	//write_seq就是下一个要分配的序号,其初始值由secure_tcp_sequence_number()基于
    	//算法生成。注意等于write_seq的序号还没有被分配
    	u32	write_seq;	/* Tail(+1) of data held in tcp send buffer */
    ...
    };
    

    2. snd_una和snd_wnd的更新

    snd_una是发送窗口的左边界,如果该字段更新,即使发送窗口大小snd_wnd没有发生变化,整个发送窗口也会前移,这样从流量控制的角度,就可以发送更多的数据(是否真的可以发送,还要考虑拥塞窗口等其它因素)。

    2.1 初始化

    可以想的到,snd_una的初始化一定发生在第一个数据段发送过程中,而snd_wnd的初始化应该是发生在第一个输入段处理过程中,所以需要客户端和服务器端分开来看。

    2.1.1 客户端初始化

    客户端对snd_una的初始化当然是发生在SYN段的发送过程中,相关代码如下:

    int tcp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
    {
    ...
    	//选择初始发送序号
    	if (!tp->write_seq)
    		tp->write_seq = secure_tcp_sequence_number(inet->saddr,
    							   inet->daddr,
    							   inet->sport,
    							   usin->sin_port);
    ...
    }
    static void tcp_connect_init(struct sock *sk)
    {
    ...
    	//发送窗口大小要从输入段首部的窗口字段获取,这时还没有任何输入段,先初始化为0
    	tp->snd_wnd = 0;
    	//初始化snd_una为第一个序号,该函数之后write_seq将会分配给SYN段
    	tp->snd_una = tp->write_seq;
    ...
    }
    

    对snd_wnd的初始化发生在收到SYN+ACK段时,相关代码如下:

    static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
    					 struct tcphdr *th, unsigned len)
    {
    ...
    	if (th->ack) {
    ...
    		tp->snd_wnd = ntohs(th->window);
    ...
    	}
    }
    

    2.1.2 服务器端初始化

    正面理解的话,服务器端对snd_una的初始化应该是发生在发送SYN+ACK段时,但是实际上不是,而是发生在收到第三次握手的ACK段时。如笔记TCP之服务器端收到ACK包所述,三次握手完成后,创建了子套接字,然后在tcp_child_process()中会继续调用tcp_rcv_state_process()处理ACK报文,代码如下:

    int tcp_child_process(struct sock *parent, struct sock *child,
    		      struct sk_buff *skb)
    {
    	int ret = 0;
    	int state = child->sk_state;
    
    	//如果用户进程没有锁住child,则让child重新处理该ACK报文,这可以让child
    	//套接字由TCP_SYN_RECV迁移到TCP_ESTABLISH状态
    	if (!sock_owned_by_user(child)) {
    		//见下文
    		ret = tcp_rcv_state_process(child, skb, tcp_hdr(skb),
    					    skb->len);
    		/* Wakeup parent, send SIGIO */
    		//child套接字状态发生了迁移,唤醒监听套接字上的进程,可能由于调用accept()而block
    		if (state == TCP_SYN_RECV && child->sk_state != state)
    			parent->sk_data_ready(parent, 0);
    	} else {
    		/* Alas, it is possible again, because we do lookup
    		 * in main socket hash table and lock on listening
    		 * socket does not protect us more.
    		 */
    		 //缓存该skb后续处理
    		sk_add_backlog(child, skb);
    	}
    
    	bh_unlock_sock(child);
    	sock_put(child);
    	return ret;
    }
    
    int tcp_rcv_state_process(struct sock *sk, struct sk_buff *skb,
    			  struct tcphdr *th, unsigned len)
    {
    ...
    	/* step 5: check the ACK field */
    	if (th->ack) {
    		int acceptable = tcp_ack(sk, skb, FLAG_SLOWPATH);
    
    		switch (sk->sk_state) {
    		case TCP_SYN_RECV:
    			if (acceptable) {
    ...
    				tcp_set_state(sk, TCP_ESTABLISHED);
    				//用ACK段中的确认号初始化本端的snd_una
    				tp->snd_una = TCP_SKB_CB(skb)->ack_seq;
    				//用输入报文的窗口字段初始化发送窗口大小
    				tp->snd_wnd = ntohs(th->window) <<
    					      tp->rx_opt.snd_wscale;
    ...
    			}
    			break;
    ...
    		}//end of switch()
    	} else
    		goto discard;
    ...
    	return 0;
    }
    

    2.2 传输过程中更新

    显然,数据传输过程中,应该在收到ACK后更新snd_una和snd_wnd。如果输入段中携带了ACK,最终都会有tcp_ack()处理确认相关的内容,相关的代码如下:

    static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag)
    {
    ...
    	u32 prior_snd_una = tp->snd_una;
    	u32 ack = TCP_SKB_CB(skb)->ack_seq;
    ...
    	if (!(flag & FLAG_SLOWPATH) && after(ack, prior_snd_una)) {
    ...
    		//快速路径情况,用ack更新snd_una,由于快速路径,所以通告的窗口大小一定
    		//没有发生变化,所以不需要更新snd_wnd
    		tp->snd_una = ack;
    		flag |= FLAG_WIN_UPDATE;
    ...
    	} else {
    ...
    		//慢速路径下,调用函数更新窗口
    		flag |= tcp_ack_update_window(sk, skb, ack, ack_seq);
    ...
    	}
    ...
    }
    
    /* Update our send window.
     *
     * Window update algorithm, described in RFC793/RFC1122 (used in linux-2.2
     * and in FreeBSD. NetBSD's one is even worse.) is wrong.
     */
    static int tcp_ack_update_window(struct sock *sk, struct sk_buff *skb, u32 ack,
    				 u32 ack_seq)
    {
    	struct tcp_sock *tp = tcp_sk(sk);
    	int flag = 0;
    	u32 nwin = ntohs(tcp_hdr(skb)->window);
    
    	if (likely(!tcp_hdr(skb)->syn))
    		nwin <<= tp->rx_opt.snd_wscale;
    
    	if (tcp_may_update_window(tp, ack, ack_seq, nwin)) {
    		flag |= FLAG_WIN_UPDATE;
    		tcp_update_wl(tp, ack, ack_seq);
    
    		if (tp->snd_wnd != nwin) {
    			//更新发送窗口大小
    			tp->snd_wnd = nwin;
    
    			/* Note, it is the only place, where
    			 * fast path is recovered for sending TCP.
    			 */
    			tp->pred_flags = 0;
    			tcp_fast_path_check(sk);
    			//如果通告的最大接收窗口发生变化,更新max_window
    			if (nwin > tp->max_window) {
    				tp->max_window = nwin;
    				tcp_sync_mss(sk, inet_csk(sk)->icsk_pmtu_cookie);
    			}
    		}
    	}
    	//用ack更新snd_una
    	tp->snd_una = ack;
    
    	return flag;
    }
    

    3. 发送窗口对发送过程的影响

    这里要明白的是,发送窗口是实现流量控制的关键,它影响的只有新数据的发送过程,与重传无关,因为重传的数据一定是在对端接收能力之内。

    TCP之数据发送(二)中有看到新数据发送的两个关键函数tcp_write_xmit()和tcp_push_one(),而且二者非常相似,参考之前的笔记中分析的tcp_snd_wnd_test()和tcp_mss_split_point()就可以明白发送窗口是如何影响发送过程的。

    展开全文
  • 查看数据是否成功发送到kafka

    千次阅读 2020-08-31 10:51:00
    查看发送到kafka的数据 kafka-console-consumer --bootstrap-server x.x.x.x:9092,x.x.x.x:9092,x.x.x.x:9092 --topic flink-sql-demo #为消费kafka消息命令,可以很好知道自己的数据有没有成功发送到kafka

    查看发送到kafka的数据
    kafka-console-consumer --bootstrap-server x.x.x.x:9092,x.x.x.x:9092,x.x.x.x:9092 --topic flink-sql-demo
    #为消费kafka消息命令,可以很好知道自己的数据有没有成功发送到kafka

    展开全文
  • 来源:苦逼的码农(ID:di201805)前言天各一方的两台计算机是如何通信的呢?在成千上万的计算机中,为什么台计算机能够准确着寻找另外台计算机,并且把数据发送给它...

    640

    来源:苦逼的码农(ID:di201805

    前言

    天各一方的两台计算机是如何通信的呢?在成千上万的计算机中,为什么一台计算机能够准确着寻找到另外一台计算机,并且把数据发送给它呢?

    可能很多人都听说过网络通信的 5 层模型,但是可能并不是很清楚为什么需要五层模型,五层模型负责的任务也有可能经常混淆。下面是网络通信的五层模型

    640?wx_fmt=png

    说实话,五层模型的具体内容还是极其复杂的,不过今天这篇文章,我将用最简洁的模式,通过网络通信的五层模型来讲解一台计算机是如何找到另外一台计算机并且把数据发送给另一台计算机的,就算你没学过计算机网络,也能够听的懂。

    1. 物理层

    一台计算机与另一台计算机要进行通信,第一件要做的事是什么?当然是要把这台计算机与另外的其他计算机连起来啊,这样,我们才能把数据传输过去。例如可以通过光纤啊,电缆啊,双绞线啊等介质把他们连接起来,然后才能进行通信。

    640?wx_fmt=png

    也就是说,物理层负责把两台计算机连起来,然后在计算机之间通过高低电频来传送0,1这样的电信号。

    2. 数据链路层

    前面说了,物理层它只是单纯着负责把计算机连接起来,并且在计算机之间传输0,1这样的电信号。如果这些0,1组合的传送毫无规则的话,计算机是解读不了的。一大堆0,1谁知道是什么鬼啊。

    640?wx_fmt=png

    因此,我们需要制定一套规则来进行0,1的传送。例如多少个电信号为一组啊,每一组信号应该如何标识才能让计算机读懂啊等等。

    于是,有了以太网协议。

    1. 以太网协议

    以太网协议规定,一组电信号构成一个数据包,我们把这个数据包称之为。每一个桢由标头(Head)和数据(Data)两部分组成。

    640?wx_fmt=png

    帧的大小一般为 64 - 1518 个字节。假如需要传送的数据很大的话,就分成多个桢来进行传送。

    对于表头和数据这两个部分,他们存放的都是一些什么数据呢?我猜你眯着眼睛都能想到他们应该放什么数据。    毫无疑问,我们至少得知道这个桢是谁发送,发送给谁的等这些信息吧?所以标头部分主要是一些说明数据,例如发送者,接收者等信息。而数据部分则是这个数据包具体的,想给接守者的内容。

    大家想一个问题,一个桢的长度是 64~1518 个字节,也就是说桢的长度不是固定的,那你觉得标头部分的字节长度是固定的吗?它当然是固定的啊,假如不是固定的,每个桢都是单独发的,那计算机怎么知道标头是几个字节,数据是几个字节呢。所以标头部分的字节是固定的,并且固定为18个字节。

    把一台计算的的数据通过物理层和链路层发送给另一台计算机,究竟是谁发给谁的,计算机与计算机之间如何区分,,你总得给他们一个唯一的标识吧?

    于是,MAC 地址出现了。

    2. MAC 地址

    连入网络的每一个计算机都会有网卡接口,每一个网卡都会有一个唯一的地址,这个地址就叫做 MAC 地址。计算机之间的数据传送,就是通过 MAC 地址来唯一寻找、传送的。

    640?wx_fmt=png

    MAC地址 由 48 个字节所构成,在网卡生产时就被唯一标识了。

    3. 广播与ARP协议

    (1). 广播

    640?wx_fmt=png

    如图,假如计算机 A 知道了计算机 B 的 MAC 地址,然后计算机 A 想要给计算机 B 传送数据,虽然计算机 A 知道了计算机 B 的 MAC 地址,可是它要怎么给它传送数据呢?计算机 A 不仅连着计算机 B,而且计算机 A 也还连着其他的计算机。    虽然计算机 A 知道计算机 B 的 MAC 地址,可是计算机 A 却不知道知道计算机 B 是分布在哪边路线上,为了解决这个问题,于是,有了广播的出现。

    在同一个子网中,计算机 A 要向计算机 B 发送一个数据包,这个数据包会包含接收者的 MAC 地址。当发送时,计算机 A 是通过广播的方式发送的,这时同一个子网中的计算机 C, D 也会收到这个数据包的,然后收到这个数据包的计算机,会把数据包的 MAC 地址取出来,与自身的 MAC 地址对比,如果两者相同,则接受这个数据包,否则就丢弃这个数据包。这种发送方式我们称之为广播,就像我们平时在广场上通过广播的形式呼叫某个人一样,如果这个名字是你,你就理会一下,如果不是你,你就当作听不见。

    (2). ARP 协议

    那么问题来了,计算机 A 是如何知道计算机 B 的 MAC 地址的呢?这个时候就得由 ARP 协议这个家伙来解决了,不过 ARP 协议会涉及到IP地址,我们下面才会扯到IP地址。因此我们先放着,就当作是有这么一个 ARP 协议,通过它我们可以知道子网中其他计算机的 MAC 地址。

    3. 网络层

    上面我们有说到子网这个关键词,实际上我们所处的网络,是由无数个子网络构成的。广播的时候,也只有同一个子网里面的计算机能够收到。

    假如没有子网这种划分的话,计算机 A 通过广播的方式发一个数据包给计算机 B , 其他所有计算机也都能收到这个数据包,然后进行对比再舍弃。世界上有那么多它计算机,每一台计算机都能收到其他所有计算机的数据包,那就不得了了。那还不得奔溃。  因此产生了子网这么一个东西。

    那么问题来了,我们如何区分哪些 MAC 地址是属于同一个子网的呢?假如是同一个子网,那我们就用广播的形式把数据传送给对方,如果不是同一个子网的,我们就会把数据发给网关,让网关进行转发。

    为了解决这个问题,于是,有了 IP 协议。

    1. IP协议

    IP协议,它所定义的地址,我们称之为IP地址。IP协议有两种版本,一种是 IPv4,另一种是 IPv6。不过我们目前大多数用的还是 IPv4,我们现在也只讨论 IPv4 这个版本的协议。

    这个 IP 地址由 32 位的二进制数组成,我们一般把它分成4段的十进制表示,地址范围为0.0.0.0~255.255.255.255。

    每一台想要联网的计算机都会有一个IP地址。这个IP地址被分为两部分,前面一部分代表网络部分,后面一部分代表主机部分。并且网络部分和主机部分所占用的二进制位数是不固定的。

    假如两台计算机的网络部分是一模一样的,我们就说这两台计算机是处于同一个子网中。例如 192.168.43.1 和 192.168.43.2, 假如这两个 IP 地址的网络部分为 24 位,主机部分为 8 位。那么他们的网络部分都为 192.168.43,所以他们处于同一个子网中。

    可是问题来了,你怎么知道网络部分是占几位,主机部分又是占几位呢?也就是说,单单从两台计算机的IP地址,我们是无法判断他们的是否处于同一个子网中的。

    这就引申出了另一个关键词————子网掩码。子网掩码和IP地址一样也是 32 位二进制数,不过它的网络部分规定全部为 1,主机部分规定全部为 0.也就是说,假如上面那两个IP地址的网络部分为 24 位,主机部分为 8 位的话,那他们的子网掩码都为 11111111.11111111.11111111.00000000,即255.255.255.0。

    640?wx_fmt=png

    那有了子网掩码,如何来判端IP地址是否处于同一个子网中呢。显然,知道了子网掩码,相当于我们知道了网络部分是几位,主机部分是几位。我们只需要把 IP 地址与它的子网掩码做与(and)运算,然后把各自的结果进行比较就行了,如果比较的结果相同,则代表是同一个子网,否则不是同一个子网。

    例如,192.168.43.1和192.168.43.2的子码掩码都为255.255.255.0,把IP与子码掩码相与,可以得到他们都为192.168.43.0,进而他们处于同一个子网中。

    2. ARP协议

    有了上面IP协议的知识,我们回来讲一下ARP协议。

    有了两台计算机的IP地址与子网掩码,我们就可以判断出它们是否处于同一个子网之中了。

    假如他们处于同一个子网之中,计算机A要给计算机B发送数据时。我们可以通过ARP协议来得到计算机B的MAC地址。

    ARP协议也是通过广播的形式给同一个子网中的每台电脑发送一个数据包(当然,这个数据包会包含接收方的IP地址)。对方收到这个数据包之后,会取出IP地址与自身的对比,如果相同,则把自己的MAC地址回复给对方,否则就丢弃这个数据包。这样,计算机A就能知道计算机B的MAC地址了。

    640?wx_fmt=png

    可能有人会问,知道了MAC地址之后,发送数据是通过广播的形式发送,询问对方的MAC地址也是通过广播的形式来发送,那其他计算机怎么知道你是要传送数据还是要询问MAC地址呢?其实在询问MAC地址的数据包中,在对方的MAC地址这一栏中,填的是一个特殊的MAC地址,其他计算机看到这个特殊的MAC地址之后,就能知道广播想干嘛了。

    假如两台计算机的IP不是处于同一个子网之中,这个时候,我们就会把数据包发送给网关,然后让网关让我们进行转发传送

    3. DNS服务器

    这里再说一个问题,我们是如何知道对方计算机的IP地址的呢?这个问题可能有人会觉得很白痴,心想,当然是计算机的操作者来进行输入了。这没错,当我们想要访问某个网站的时候,我们可以输入IP来进行访问,但是我相信绝大多数人是输入一个网址域名的,例如访问百度是输入 www.baidu.com 这个域名。其实当我们输入这个域名时,会有一个叫做DNS服务器的家伙来帮我们解析这个域名,然后返回这个域名对应的IP给我们的。

    因此,网络层的功能就是让我们在茫茫人海中,能够找到另一台计算机在哪里,是否属于同一个子网等。

    4. 传输层

    通过物理层、数据链路层以及网络层的互相帮助,我们已经把数据成功从计算机A传送到计算机B了,可是,计算机B里面有各种各样的应用程序,计算机该如何知道这些数据是给谁的呢?

    这个时候,端口(Port)这个家伙就上场了,也就是说,我们在从计算机A传数据给计算表B的时候,还得指定一个端口,以供特定的应用程序来接受处理。

    也就是说,传输层的功能就是建立端口到端口的通信。相比网络层的功能是建立主机到主机的通信。

    也就是说,只有有了IP和端口,我们才能进行准确着通信。这个时候可能有人会说,我输入IP地址的时候并没有指定一个端口啊。其实呢,对于有些传输协议,已经有设定了一些默认端口了。例如http的传输默认端口是80,这些端口信息也会包含在数据包里的。

    传输层最常见的两大协议是 TCP 协议和 UDP 协议,其中 TCP 协议与 UDP 最大的不同就是 TCP 提供可靠的传输,而 UDP 提供的是不可靠传输。

    5.  应用层

    终于说到应用层了,应用层这一层最接近我们用户了。

    虽然我们收到了传输层传来的数据,可是这些传过来的数据五花八门,有html格式的,有mp4格式的,各种各样。你确定你能看的懂?

    因此我们需要指定这些数据的格式规则,收到后才好解读渲染。例如我们最常见的 Http 数据包中,就会指定该数据包是 什么格式的文件了。

    总结

    五层模型至此讲到这里。对于有些层讲的比较简洁,就随便概况了一下。因为如果我说的详细一点的话,篇幅肯定会特别特别长,我着已经是尽最大的努力以最简洁的方式来讲的了。如果你想详细去了解,可以去买计算机网络相应的资料,强烈推荐《计算机网络:自顶向下》这本书。希望我的讲解能让你对计算机之间数据的传输有个大概的了解。

    (完)


    640?

    Java团长

    专注于Java干货分享

    640?wx_fmt=jpeg

    扫描上方二维码获取更多Java干货

    展开全文
  • 一个数据包从发送到接收在网络中经历了那些过程 假设学生给老师发送电子邮件,内容为:“老师您好!”。从计算机A向另台计算机B发送电子邮件,站在网络原理的角度来分析整个过程。 启动应用程序新建邮件,收件...

    一个数据包从发送到接收在网络中经历了那些过程

    假设学生给老师发送电子邮件,内容为:“老师您好!”。从计算机A向另一台计算机B发送电子邮件,站在网络原理的角度来分析整个过程。

    1. 启动应用程序新建邮件,将收件人邮箱和邮件内容填写好,应用程序进行编码处理。(应用层

    2. 应用在发送邮件那一刻建立TCP连接(三次握手),将数据交给传输层

      第一次握手:建立连接时,主机A向主机A发送请求报文
      第二次握手:主机B收到请求报文后,如同意连接,则向主机A发送确认报文
      第三次握手,主机A收到主机B的确认后,再次向主机B给出确认报文,完成连接

    3. TCP 就会把这个数据构成一个TCP数据报(附加上TCP首部包括源端口号和目标端口号(用以识别发送主机跟接收主机上的应用)、序号(标明发送的包那部分是数据)以及校验和(判断数据是否被更改)),然后将该数据报交给IP协议(网络层)。

    4. IP协议就会构造一个IP数据报(IP会将TCP传过来的数据报当作自己的数据,加上IP首部包含接收端IP地址以及发送端的IP地址),此处要根据数据报的长度,以及MTU的限制,考虑是否进行分包,查路由表决定从哪一个端口转发,将数据交给数据链路层

    5. 数据链路层将数据构造一个以太网数据帧,其中以太网首部包含接收端MAC地址、发送端MAC地址以及标志以太网类型的以太网数据的协议。源mac就是本机mac,目的mac根据上面IP确定的转发端口来决定(基于mac学习完成,ARP查找)

    数据报的结构:
    在这里插入图片描述

    1. 数据到达物理层,物理层将数据报转换成光电信号或者电信号进行传输;
    2. 首先传输到下一台路由器上,路由器进行解析和分用(解析到传输层)NAT 路由选择 ,继续查路由表,把数据再次封装的,往下一个路由器设备上转发(在这里封装和分用和上边是一样的)
    3. 中间会经过若干个路由器转发的过程,最终到达目的服务器;
    4. 服务器就会进行分用。物理层把光电信号转成二进制bit流,交给数据链路层;
    5. 数据链路层从以太网数据报的首部找到MAC地址判断是否为发给自己的包,如果不是发给自己的数据则丢掉。如果是就解析出其中的IP数据报交给网络层,但是如果是无法识别的协议类型也会丢掉。
    6. 网络层收到数据报,同样进行解析判断自己是不是首部中的目标IP,如果是则接收数据包并查找上一层的协议类型,如果是TCP就交给TCP处理如果是UDP就交给UDP处理。网络层可能需要组包(取决于第4步是否分包),组包后将数据交给传输层;
    7. 传输层TCP收到数据,首先计算校验和保证数据的完整性,然后按照序号检查接收数据,检查端口号确定具体的应用程序 ,将解析出的应用层数据,交给应用程序,返回ACK(确认序号、窗口大小、延时应答、捎带应答)在这里ACK也是一个TCP数据报,也会涉及到一系列的封装和分用过程,如果没有收到ACK就会反复发送。
    8. 服务器的应用程序读取数据,解析数据获知邮件的收件人信息以及邮件内容。(应用层
    9. 主机B给发送端返回一个回执信息。
    10. 断开连接(四次挥手)
      第一次挥手:主机A想分手,发送消息给主机B
      第二次挥手:主机B通知主机A已经接受到分手请求,但还没做好分手准备
      第三次回收:主机B已经做好分手准备,通知主机A
      第四次挥手:主机A发送消息给主机B,确定分手,主机B关闭连接

    基本上就是这样一个过程,我在慢慢在细化每一个过程。

    参考文献
    【图解HTTP读书笔记】第一章:了解Web及网络基础
    【图解HTTP读书笔记】第二章:简单的HTTP协议
    【图解HTTP读书笔记】第三章:HTTP报文内的HTTP信息
    【图解HTTP读书笔记】第四章:返回结果的HTTP状态码
    【图解HTTP读书笔记】第五章:与HTTP协作的Web服务器
    【图解HTTP读书笔记】第六章:HTTP首部
    【图解HTTP读书笔记】第七章:确保Web安全的HTTPS
    【图解HTTP读书笔记】第八章:Session 和 Cookie工作原理
    【图解TCP_IP读书笔记】第一章:网络基础知识
    【图解TCP_IP读书笔记】第二章:TCP/IP 基础知识
    ----------------------------------------------------------------------------------
    TCP协议 十大特性详解(上)
    TCP协议 十大特性详解(中)
    TCP协议 十大特性详解(下)
    展开全文
  • 是火狐的一个提示功能主要是防止同一页面的数据反复提交; 解决方法: 不要用location.reload();来刷新页面,可以重定向请求来达到刷新页面效果。 转载于:...
  • 四、 后退 N 帧协议 发送数据分类、 五、 后退 N 帧协议 发送方 需要 响应的事件、 六、 后退 N 帧协议 接收方 需要 响应的事件、 七、 后退 N 帧协议 运行细节、 八、 后退 N 帧协议 滑动窗口长度、 九、 ...
  • UDP之数据发送过程

    千次阅读 2018-12-08 02:15:13
    当应用程序调用send()等系列系统调用向UDP套接字写数据时,最终会调用UDP的udp_sendmsg(),这篇笔记就以该函数为入口分析UDP对发送数据包的处理过程。 1. 基本特性 在分析代码之前,有必要对一些UDP的写操作...
  • 在这篇文章中我介绍一下如何通过串口发送一帧存在结构体中的数据。通过串口接受一帧数据请参考的我博客中的文章——教你如何使用stm32接收一帧数据! 一:在.h首先定义一结构体。 typedef struct { uint8_t H1;...
  • 2、把拥塞窗口cwnd设置为1最大报文段MSS大小, 3、再次从慢启动阶段开始。发生拥塞后 开始慢启动 cwnd=1KB,之后呈指数增长。 经过1RTT cwnd=2^1=2KB 经过2RTT cwnd=2^2=4KB, 此时到达门限值ssthresh,之后 ...
  • ZigBee组网实验:多终端节点向协调器发送数据&amp;协调器给终端节点发送数据 ... 2018年06月04日 08:35:29 mchen_6431 阅读...本节介绍一个终端节点发送数据,协调器接收并打印串口上的例子。对应的程序代码:...
  • 最近用stm32编写串口发送程序,在硬件方面需要做如下准备: 1.stm32开发板,这里我的是stm32f...3.如何实现软件串口助手和硬件单片机的连接呢,我们还需要一个 USB-TTL,即 没有串口的 电脑,用 USB 接口 与 TTL ...
  • LoRa学习:LoRa数据接受发送流程(FIFO)

    万次阅读 多人点赞 2017-09-21 11:06:03
    LoRa学习:LoRa数据接受发送...从上图可以看出,LoRa发送前一直处于待机状态,在初始化Tx模块后,发送数据(Payload)写入FIFO,然后切换到发送状态将数据通过LoRa调制成信号发送出去,等到发送完成后,会产生TxDo
  • BLE(4)—— 数据发送接收流程

    千次阅读 2019-07-08 00:17:33
    基于 BLE 5.1 协议 Core Spec。 BLE 数据收发,从 RF 发送/...数据发送端(TX)经过可选的加密(取决连接状态启动加密与否),根据 PDU,启动加密引擎(硬件or软件,具体看实现)计算 CRC,数据白化后,通过 RF 发...
  • 目的是通过NB-IoT协议将数据发送到服务器端。  现在已有不少NB-IoT模块,本人采用的是移远的BC95模块。  接线:外接电源供电 串口接右角三接口,GND,TXD,RXD分别和USB转TTL线的GND、RXD、TXD连接。3.3V不...
  • 现在在做一个通过socket给位机发送硬件控制指令的项目,以前使用串口,流程好控制,都是同步的:发送-->等待N毫秒-->接收数据-->处理数据,现在要改成网口,可是socket的发送和接收不在一个方法中,导致我没法实现...
  • 1,主机A首先在本局域网中广播发送一个ARP请求分组,其内容可以形象描述为:“我的IP地址是A,硬件地址是a,我想知道IP地址为B的主机硬件地址”。本局域网中的所有运行ARP的主机都会收到该ARP请求分组。 2,主机B...
  • RTT:Round-Trip Time,往返时延,表示从发送发送数据开始,到发送端收到来自接收端的确认(接收端收到数据后便立即发送确认),总共经历的时延。TCP传输大块数据时,肯定需要进行数据分段,而每分段所能携带的...
  • 7 TCP协议发送数据: 注意:tcp的是 客户端和服务端。客服端可以主动访问服务端,服务端不能主动访问客户端。 但是在建立联系之后,就可以互相访问了。 创建发送端Socket对象(创建对象,并且需要指向服务器的ip地址...
  • 一个http请求发送到后端的详细过程

    万次阅读 多人点赞 2016-06-13 11:30:34
    根据这些数字,发送的一方不断的进行发送等待确认发送一个数据段后,会开启一计数器,只有当收到确认后才会发送,如果超过计数时间仍未收到确认则进行重发,在接受端如果收到错误数据,则其丢弃,这...
  • 本节介绍一个终端节点发送数据,协调器接收并打印串口上的例子。对应的程序代码: ZStack-CC2530-2.5.1a\Projects\zstack\Samples\SendTest 对应的代码包:...
  • 解决QT连续发送数据的问题

    千次阅读 2018-07-19 19:18:06
    1、收到的数据不全,只有第一个 2、收不 3、收到的数据不对 readyRead在信号到达时,开始接收,我即使调用几次write,也不能解决这问题。 我尝试了几方法(发送的是结构体) 1、加延时,在write的时候,...
  • 关于websocket发送数据格式问题

    千次阅读 2019-05-20 02:38:14
    众所周知,大家在开发websocket的时候都会使用类似于“心跳”的方式来检查前后台是否断开连接了,在打开websocket的时候,有一onopen的回调,在里面前端开启一定时器,每隔几十秒给后台发送一个ping消息,后台...
  • 在项目中,遇到一个socket接口,需要由我们系统封装为webservice,然后向外提供,在封装的过程中,遇到了一个问题: 根据对方提供的地址和端口,我直接通过telnet可以发送数据,但是通过程序却无法发送数据。我首先...
  • VC上位机MFC利用串口控件发送接收数据

    万次阅读 热门讨论 2016-01-05 10:02:09
    经过这两天的调试,基本上搞定了dsp和机器人上位机界面,先记录我的上位机。  实验室是做机器人控制的,经常会用到上位机,我只搞过...串口发送和接收数据,2.手柄扫描(因为实验室用手柄来遥控机器人,扫描到手
  • 请教几问题,困惑很久了。 1.比如手机客户端和服务端连接,手机突然断网了,但此时服务端没检测,还在...有什么方法能明确是数据发送成功了的。 2.处理了占包拆包的情况,怎么服务端发的数据有时客户端收不
  • 消息确认是保证消息传递可靠性的重要步骤,上一节我们说持久化,持久化只能保证消息不丢失,但是如果消息如果投递失败我们怎么进行补偿操作呢?解决办法就是实现回调函数进行操作,在消息的发送和消息的消费都可以...
  • nodejs实现Websocket的数据接收发送

    万次阅读 2018-04-03 17:41:56
    nodejs实现Websocket的数据接收发送 在去年的时候,写过篇关于websocket的博文:http://www.cnblogs.com/axes/p/3586132.html ,里面主要是借助了nodejs-websocket这插件,后来还用了socket.io做了些demo,...
  • TCP的数据发送和接收

    万次阅读 2013-10-25 14:12:20
    TCP通信的单位是一个报文,TCP报文包括报文头部和数据部分,头部最少占用20字节。运用TCP协议进行通信前需要建立连接(三次握手),数据传输完成后,最后需要断开连接(4次握手)。  TCP发送缓存和接收缓存,TCP...
  • Stm32串口接收和发送数据--基础

    千次阅读 2019-01-23 22:38:39
    STM32从傻子智障 你今天有的时间是后来的你所梦寐以求的,加油哇! 通讯协议,百度,大同小异。 USART,通用同步异步收发器 左边引脚部分: ...发送时,TDR寄存器内容发送到移位寄存器,位...
  • TCP 带外数据(即紧急模式的发送和接受)

    千次阅读 多人点赞 2018-09-13 17:36:24
       首先给出OSI 参考模型与TCP/IP协议模型图: 如上图所示,我们的 TCP 位于传输层,下面还有互联网层(主要是IP...首部之后就是用户数据 ,再来次图: 在这里,我们只关心以下两部分: 紧急字段URG:...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 813,761
精华内容 325,504
关键字:

为了确定将数据发送到下一个