CAN201 W4

This’s the note of introduction to networking Week4.
This week we will talk about the transport layer in networking system. 传输层

  • Roadmap
    1. Transport-layer services
    2. Multiplexing and demultiplexing
    3. Connectionless transport: UDP
    4. Principles of reliable data transfer

Lecture

Transport-layer services

Transport services and protocols

  • Provide logical communication between app processes running on different hosts 端与端之间
  • Transport protocols run in end systems 在这里我们可以发现,之前讲的五层模型只出现于端处,在路由上只有三层,没有五层。
    • Send side: breaks app msg into segments, passes to network layer 发送端:将应用程序消息分成段,传递到网络层
    • Rcv side: reassembles segments into messages Rcv端:将段重组为消息
  • Transport-layer protocols for Internet: TCP and UDP

Transport services and protocols


  • Network layer: logical communication between hosts 网络层:主机之间的逻辑通信。
  • Transport layer: logical communication between processes: Relies on, enhances, network layer services. 传输层:进程之间的逻辑通信:依赖、增强网络层服务。

假如把信息的传递表示称Ann家12个孩子和Bill家12个孩子的通信,那么Transport protocol就是Ann和Bill家负责收集和分发12封信的服务,而Network-layer protocol则是家庭与家庭之间的邮政服务。


Internet transport-layer protocols

  • Reliable, in-order delivery (TCP) 可靠,有序交付
    • Congestion control 拥塞控制
    • Flow control 流量控制
    • Connection setup 建立连接
  • Unreliable, unordered delivery: UDP 不可靠,无序交付
    • 多路复用解复用
    • No-frills extension of “best-effort” IP “尽最大努力”IP的无虚饰扩展
  • Services not available: 服务不可用 TCP和UDP都不可以
    • Delay guarantees 延迟保证
    • Bandwidth guarantees 带宽保证

Multiplexing and demultiplexing 多路复用和多路分用

多路复用和解复用
发送端:Multiplexing从多个socket接收消息,然后打包成一个segment发送出去。
接收端:通过发送端封装上的头部信息把消息分发到每一个socket上。
How demultiplexing works

  • Host receives IP datagrams 主机接收IP数据报
    • Each datagram has source IP address, destination IP address 每个数据报都有源IP地址、目的IP地址
    • Each datagram carries one transport-layer segment 每个数据报携带一个传输层段
    • Each segment has source, destination port number 每个段都有源端口号、目的端口号
  • Host uses IP addresses & port numbers to direct segment to suitable socket 主机使用IP地址和端口号直接段到合适的套接字


Connectionless demultiplexing (UDP)

因为UDP是没有连接的,所以只要IP datagram里的目标IP地址和端口号是一样的,都会送到相同的socket中,不管这个datagram是否来自于同一个进程。


Connection-oriented demux

socket被分开了,UDP里只要接受的IP和port不变,就用一个socket接受。
但是TCP只要发送的IP和port不一样,即使接受的IP和port一样,也会重新开port。
threaded server: 线程多进程


Connectionless transport: UDP

UDP: User Datagram Protocol

Feature:

  • Simple and straightforward
  • Best effort
  • Lost
  • Connectionless
    • No handshaking
    • Each UDP segment handled independently of others: Out-of-order to APP
  • UDP use:
    • Streaming multimedia apps
    • DNS
  • Reliable transfer over UDP:
    • Add reliability at application layer 应用层解决
    • Application-specific error recovery 错误恢复手段

UDP: segment header
segment header


UDP checksum
Goal: detect “errors” in transmitted segment 检测传输段中的“错误”
Sender:

  • Treat segment contents, including header fields, as sequence of 16-bit integers 将段内容(包括报头字段)作为16位整数序列处理
  • Checksum: addition (one’s complement sum) of segment contents 校验和:段内容的添加(一个的补和) 负责检查传输有没有出错
  • Sender puts checksum value into UDP checksum field 发送端将校验和值放入UDP校验和字段

Receiver:

  • Compute checksum of received segment 计算接收报文段的校验和
  • Check if computed checksum equals checksum field value: 检查计算的checksum是否等于checksum字段值:
    • NO - error detected
    • YES - no error detected. But maybe errors nonetheless?

在信息发送过来的时候会携带一个checksum,然后接收到之后拿16bits相加,多出来的第一位加到结尾。得出一个sum,然后在根据sum全部翻转过来,得到checksum。最后对比算出来的checksum和发送过来的checksum,假如一样说明没有问题,假如不一样就说明接受或发送出现了问题。


Principles of reliable data transfer

可靠数据传输的原理,参见书和ppt。
rdt1.0, rdt2.0, rdt2.1, rdt3.0
rdt 1.0
rdt 2.0是面对比特错误是使用的方法。假如收到的消息没有问题就发送ACK,有问题就发送NAK,然后发送者接收到返回的消息再继续进行下一阶段的发送,所以只需要两个状态就可以解决问题。
rdt2.0 has a fatal flaw!
What happens if ACK/NAK corrupted? 如果ACK/NAK损坏会发生什么

  • Sender doesn’t know what happened at receiver! 发送方不知道接收方发生了什么
  • Can’t just retransmit: possible duplicate 不能只是重传:可能重复

Handling duplicates:

  • Sender retransmits current pkt if ACK/NAK corrupted
  • Sender adds sequence number to each pkt
  • Receiver discards (doesn’t deliver up) duplicate pkt

所以就多加了两个状态变成rdt2.1
rdt2.1
rdt2.1 Discussion

在rdt2.2中去掉了NAK,只用ACK,假如checksum出现问题就反复回府之前的申请,直到可以进入下一个状态再继续。
rdt 2.2

rdt 3.0继续解决了丢包的情况:通过加上time设置。
利用率低,因为是停等协议。


Lab

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
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# client
import json
from socket import *
import argparse


def _argparse():
parser = argparse.ArgumentParser(description="This is description!")
parser.add_argument('--ip', action='store', required=True, dest='ip', help='IP address')
parser.add_argument('--input', type=str, required=True, dest='input', help='The path of input file')
parser.add_argument('--port', type=int, required=True, dest='port', help='The port of server')
return parser.parse_args()


def main():
parser = _argparse()
server_name = parser.ip
server_port = parser.port
clientSocket = socket(AF_INET, SOCK_STREAM)
clientSocket.connect((server_name, server_port))
clientSocket.send(parser.input.encode())
feedback_command = clientSocket.recv(20480).decode()
feedback = json.loads(feedback_command)
print(feedback)

clientSocket.close()


if __name__ == '__main__':
main()


# server
import json
from socket import *
import argparse


def _argparse():
parser = argparse.ArgumentParser(description="This is description!")
parser.add_argument('--ip', action='store', required=True, dest='ip', help='IP address')
parser.add_argument('--input', type=str, required=True, dest='input', help='The path of input file')
parser.add_argument('--port', type=int, required=True, dest='port', help='The port of server')
return parser.parse_args()


def main():
parser = _argparse()
server_port = parser.port
server_socket = socket(AF_INET, SOCK_STREAM)
server_socket.bind(('', server_port))
server_socket.listen(2)
print('The server is ready to receive')

while True:
connectionSocket, addr = server_socket.accept()
receive_command = connectionSocket.recv(20480).decode()
receive_message = json.loads(receive_command)
print(receive_message)
print(type(receive_message))
connectionSocket.send(parser.input.encode())

connectionSocket.close()


if __name__ == '__main__':
main()

作者

Felix Chen

发布于

2021-10-02

更新于

2021-10-17

许可协议

评论