TCP/IP 基础复习

tcp/ip

学习

TCP/IP的四层协议栈: 应用层,传输层,网络层,链路层

TCP and UDP 传输层的传输协议不同

其他差异可借鉴:传送门

TCP/IP协议栈中的各层的作用

  1. 物理层:解决的是传输0和1的问题
  2. 链路层:解决的是数据从源地址到目的地址传输的问题,通过MAC地址在自己的局域网内,以及通过L2交换机维护MAC地址和网口的映射表,来确保子网的数据有序的传输。
    问题:既然局域网是用MAC地址就可以通信,为什么还需要IP地址? 局域网用MAC通讯为什么还要IP?
    可以这么理解,只用MAC地址是完全可以在局域网通信,但一般的电脑设备没有提供只使用MAC地址来传输数据的“口子”,电脑最终还是要连接互联网的,要连外网必须使用IP地址,索性使用应用层一层一层向下调用,给用户留出统一的接口。
  3. 网络层:通过IP地址解决的是跨子网之间的数据传输,L3交换机维护路由表。
  4. 传输层:TCP和UDP协议,端口区别进程。
  5. 应用层:http ftp
windows 和linux 的不同
头文件:
	win <winsock2.h> 需要插入进项目的头文件以codeblocks是插入bilwsock32.a
	linux <unistd.h>.<arpa/inet.h>.<sys/socket.h>

套接字类型

  1. 面向连接 SOCK_STREAM
  2. 面向消息 SOCK_DGRAM

函数

int socket(int domain, int type, int protocol); 创建套接字

​ 成功返回文件描述符,失败返回-1;
domain 协议族 一般用PF_INFT ipv4互联网协议族
type 传输类型

  1. 面向连接 SOCK_STREAM 特点 数据不会消失 按顺序 不存在边界

  2. 面向信息 SOCK_DGRAM 不按顺序 会丢失 有边界 限制大小

protocol 协议信息

  1. IPPROTO_TCP tcp套接字用于IPv4和面向连接
  2. IPPROTO_UDP UDP套接字用于IPv4和面向消息

网络地址分类与主机地址边界


首字节

A 类 0~127 开头 0
B 类 128~191开头 10
C 类 192~223 开头 110

字节序htons中

hton~s 表示把short型数据从主机转网络字节序
h:主机host n: 网络network s: short 型(l: long 型)
h和n可互相替换 表示谁转谁

初始化和分配地址


<arpa/inet.h>
int inet_aton(char *string, struct in_addr *addr) 与 in_addr_t inet_addr(char *string) 作用相同
1 成功 0 失败 成功返回32位 大端序整数型,失败返回INADDR_NONE

地址转码本机转网络是颠倒的 也就是小端序转大端序 颠倒方式如下按字节颠倒

0x1234 -> 0x3412

127.232.124.79 ->0x4f7ce87f

用二进制来看就是 0111 1111.1110 1000.0111 1100. 0100 1111 -> 0100 1111 0111 1100 1110 1000 0111 1111

TCP

默认函数调用顺序

服务端: 创建套接字 -> 分配地址 -> 等待连接请求 -> 允许连接 -> 数据交换 -> 关闭

客户端: 创建套接字 -> 请求连接 -> 数据交换 -> 断开连接

UDP

客户端与服务端相同不区分。

特点sendto在判断没有分配过地址时会自动分配地址

函数调用过程: 创建套接字->分配地址->数据交换->关闭

以上属于默认的未连接套接字。

每次注册目标套接字进行传输

同样还有已连接套接字

和TCP一样调用connect即可得到固定的目标套接字,发送消息的时候就也可以用write 和read了

connect 在这里不代表连接,只是在套接字中注册了目标的IP和端口信息

tcp/ip原理


I/O 缓冲

write() 调用时 ,会将数据带入输出缓冲,在适合的时候传入对方输入缓冲

read() 调用时, 会读取输入缓冲的数据。

特性:

  1. I/O缓冲在每个tcp套接字中单独存在
  2. 在创建套接字时自动生成
  3. 关闭套接字也会继续传递输出缓冲遗留的数据
  4. 关闭套接字会丢失输入缓冲的数据

不会发生超过输入缓冲大小的数据传输:

​ TCP中有滑动窗口协议-》相当与一次对话

套接字主要经过:

​ 与对方建立连接
​ 与对方数据交换
​ 断开连接

建立连接:三次握手

​ 也就是TCP在建立连接时的三次对话:

​ 客户端先发请求,服务端接收并回复准备就绪,客户端再次回复收到受理答复。

收发数据前的准备:建立连接

客户端首次请求连接时用的消息 称SYN:SEQ:A数据包编号, ACK:-

接下来到服务端回复: SYN+ACK : SEQ:B数据包编号, ACK:A+1 也就是概述接收到并且提醒你下次要传递的编号,同时告诉自己的。

客户端再次回复:ACK:SEQ: A+1, ACK:B+1

SEQ 表示自己所发的数据包编号

ACK 表示告知你收到对方的时ACK-1 同时告诉对方下一个该发ACK编号的数据包了

数据交换:回复一下即可

发送者先发送 SEQ: 数据包编号

接收者回复 ACK:收到的编号+字节数+1 同时也表示告诉发送者下次发送的编号,和所收到消息的回应。

如果中途没收到超时会重发-------

断开连接:四次握手

本方要断开的先发送 FIN:SEQ A同上 ACK -

另一方回复:ACK : SEQ B同上 ACK:A+1

另一方准备后再次发送: FIN : SEQ B+1 ACK: A+1

最后本方 回复: ACK SEQ A+1 ACK:B+2

同样以编号大小来得知情况

优美的断开套接字连接


主要断开连接函数有:

shutdown(int sock, int howto) 关闭一个流 
    主要参数有:sock 套接字
    		howto 关闭的流类型 
    SHUT_RD 断开输入流 会使之没有数据能进来
    SHUT_WR 输出流 会使之不能出去
    SHUT_RDWR 断开两个 两个都不能
close(int sock) 关闭套接字

优美的方法就是在发送完自己的数据后

先关闭输出流,再执行读操作在关闭所有。。。

发布了74 篇原创文章 · 获赞 29 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/ClonH/article/details/104267503