- IP数据包中包含有源地址和目的地址
- TCP(Transmission Control protocol)协议是一种可靠的面向连接的,是传输层通讯协议
- UDP(User Datagram Protocol)用户数据报协议,是一种面向无连接的,是传输层通讯协议,其三个特点与TCP刚好相反
- 网卡,又称为网络适配器,每个网卡都有一个编号,称为MAC地址,用于标识网络设备,类似于身份证
- ipv4占32位,ipv6占128位
- 实际大多通过子网掩码来区分网络位和主机位,子网掩码跟IP地址一一对应,子网掩码为1的是网络位,为0的是主机位。
如:192.168.1.2 掩码255.255.255.0 。网络位(子网ID)192.168.1 主机位(主机ID)是2 - 子网ID不同的网络不能直接通信,如果要通信要通过路由转发
- 主机ID全为0的IP地址表示网段地址,主机ID全为1的IP地址表示该网段的广播地址,这两地址不能给你分配,也就是比如192.168.1.X,只能分配192.168.1.1-192.168.1.254
- 127.0.0.1称为回环地址,通过ipconfig中查看的lo就是回环,同一个系统里的两个进程就可以用这个地址进行通信
- 子网掩码必须和IP地址一起用,
- 192.168.2.73/255.255.255.0 和192.168.2.73/24是子网掩码的两种表现形式,24代表1的数量
- ifconfig eth0 10.0.31.96 netmask 255.255.255.0 这个是手动配置子网掩码
这里的0806都是十六进制数
- IEEE802.2/802.3封装常用在无线,以太网封装常用在有线局域网
- TCP相当于打电话,UDP相当于发送微信信息
- 上图代码判断大小端
- htonl,htons指的是host->network,ntohl,ntohs指的是net->host,l代表int,s代表short
- uint16_t htons(uint16_t hostint16),这个是转换16位字节序,
- uint32_t ntohl(uint32_t hostint32),uint16_t ntohs(uint16_t hostint16)同理
- 因为人为看IP地址其实是个字符串,机器看的话是个int整型,所以要转换
- const char*inet_ntop(int family,const void*addrptr,char* strptr,size_t len);这个函数相反,其中len表示strptr缓存区的长度,len的宏定义如下:
- family这个参数先传AF-INET(ipv4),如果要传v6,就AF_INET6
- in_addr_t inet_addr(const char* cp) 和char* inet_ntoa(struct in_addr in)这两个函数功能和上面两个函数一样,只是这两个函数只能用于ipv4,而上面的v4,v6都可以,
- 对于海量数据传输不应该使用UDP,广播和多播必须使用UDP
- UDP应用,DNS(域名解析),NFS(网络文件系统),RTP(流媒体)
- socket是一种文件描述符,代表了一个通信管道的一个端点,所以可以用read等函数对其进行网络数据的收发和发送等操作,得到socket的函数为socket()
- int bind(int sockid,const struct sockaddr* addr,socklen_t addrlen),socket与网络信息结构体绑定函数
- ssize_t recvfrom(int sockid,void* buf,size_t len,int flags,struct sockaddr* src_addr,socklen_t *addrlen),接收数据函数,其中src_addr保存的是对方的网络信息
- UDP传输自带多线程,也就是多个客户端可以给一个服务端发消息
- TFTP协议分析:第一行,读写请求(1/2(RDWR)),1代表读,也就是下载,2代表写,也就是上传,都是相对于客户端,所以读写请求如果是下载,格式为"01text.txt0octet0"
-
广播
- 广播的目的MAC是fffff,目的IP为xx.xx.xx.255:port,该网段下所有都会收到广播,但是到了传输层,对比port一致的才会最终接收,其他Port不一致的都会丢弃
-
int setsockopt ( int socket , int level , int option_name , const void * option_value , socklen_t option_len );功能:设置一个套接字的选项(属性)level:协议层次SOL_SOCKET 套接字层次IPPROTO_TCP tcp 层次IPPROTO_IP IP 层次option_name :选项的名称SO_BROADCAST 允许发送广播数据(SOL_SOCKET层次的)option_value :设置的选项的值 , int 类型的值,存储的是 bool 的数据( 1 和 0 )0 不允许 1 允许option_len : option_value 的长度返回值: 成功: 0 失败: ‐ 1
-
多播:数据的收发仅仅在同一分组中进行,所以多播又称之为组播多播的特点:1、多播地址标示一组接口2、多播可以用于广域网使用3、在IPv4中,多播是可选的
-
多播地址IPv4的D类地址是多播地址十进制:224.0.0.1~239.255.255.254十六进制:E0.00.00.01~EF.FF.FF.FE多播地址向以太网MAC地址的映射
-
3.3 多播流程发送者:第一步:创建套接字 socket()第二步:向多播地址发送数据 sendto()接收者:第一步:创建套接字 socket()第二步:设置为加入多播组 setsockopt() 第三步:将套接字与多播信息结构体绑定 bind()第五步:接收数据
-
int setsockopt ( int socket , int level , int option_name , const void * option_value , socklen_t option_len );功能:设置一个套接字的选项(属性) :level :IPPROTO_IP IP层次option_name :IP_ADD_MEMBERSHIP 加入多播组option_value :设置的选项的值struct ip_mreq{struct in_addr imr_multiaddr ; // 组播 ip 地址struct in_addr imr_interface ; // 主机地址INADDR_ANY 任意主机地址(自动获取你的主机地址)};option_len : option_value 的长度返回值: 成功: 0 失败: ‐ 1
-
TCP
-
TCP编程流程服务器:创建套接字 socket()将套接字与服务器网络信息结构体绑定 bind()将套接字设置为监听状态 listen()阻塞等待客户端的连接请求 accept()进行通信 recv()/send()关闭套接字 close()客户端:创建套接字 socket()发送客户端连接请求 connect()进行通信 send()/recv()关闭套接字 close()
- int connect(int sockid, const struct sockaddr* addr, socklen_t *addrlen)
- ssize_t send(int sockid, const void* buf, size_t len, int flags),
- ssize_t recv(int sockid, const void* buf, size_t len, int flags),
-
如果发送端关闭文件描述符或者关闭进程,则 recv 函数会返回 0
- TCP协议不能发送长度为0的数据包,UDP可以
- int listen(int sockfd,int backlog); 其中backlog为允许通信连接的主机个数,一般为5,10
- int accpet(int sockid, struct sockaddr* addr, socklen_t *addrlen),阻塞等待连接,成功,返回新的文件描述符,(只要有客户连接,就会产生新的文件描述符,这个新的文件描述符专门与指定客户端进行通信的)
- 注意,在服务端,socket和accpet都是返回一个文件描述符,但是真正与客户端通信的的accept的返回值(来一个客户他就会返回一个新fd),socket的返回值只是负责连接,所有在accept后要调用的fd是accept返回的fd,accept之前的包括accept调用的是socket返回的fd
-
1、使用close函数即可关闭套接字关闭一个代表已连接套接字将导致另一端接收到一个0长度的数据包2、做服务器时1>关闭监听套接字将导致服务器无法接收新的连接,但不会影响已经建立的连接2>关闭accept返回的已连接套接字将导致它所代表的连接被关闭,但不会影响服务器的监听3、做客户端时关闭连接就是关闭连接,不意味着其他
- 客户端给服务器发送connect请求时,会先发送一个SYN,值为J,然后服务器收到后会回复一个ACK(应答),值为J+1和SYN,值为K,然后客户端收到后,会回复一个ACK,值K+1,三次握手完成,代表连接成功
-
TCP原本不是并发服务器,TCP服务器同一时间只能与一个客户端通信
-
TCP不能实现并发的原因:由于TCP服务器端有两个读阻塞函数,accept和recv,两个函数需要先后运行,所以导致运行一个函数的时候另一个函数无法执行,所以无法保证一边连接客户端,一边与其他客户端通信
-
网络通信
- 交换机工作在链路层,用于同一个网段的数据传输,路由器(Router,又称为网关设备gateway)工作在网络层,可用于不同网段的数据传输
- 不在同一网段的PC,需要设置默认网关才能把数据传送过去 通常情况下,都会把路由器设为默认网关 当路由器收到一个其它网段的数据包时,会根据“路由表”来决定把此数据包发送到哪个端 口; 路由表的设定有静态和动态方法 设置路由表就是设置下一跳,指定当前网段的主机与另一个网段主机通信是数据报应该交给 那个路由器
- UDP和TCP有各自独立的端口,一个进程可同时拥有多个端口
- SOCK_RAW原始套接字,SOCK_DGRAM用于UDP, SOCK_STREAM用于TCP
- int socket(int domain, int type, int protocol); 功能:创建套接字,返回文件描述符 domain:通信域,地址族 AF_PACKET,PF_PACKET type:套接字类型 SOCK_RAW protocol:附加协议 #include <netinet/ether.h> ETH_P_ALL 所有协议对应的数据包 ETH_P_IP ip数据 包 ETH_P_ARP arp数据包,这个参数要htons(ETH_P_ALL) 返回值: 成功:文件描述符 失败:‐1
- 因为原始套接字属于底层,所以在运行时,要加上sudo,也就是sudo ./a,out
- 而且它recvfrom(),recv(),read()都可以用,它接收到的就是整个数据包,也就是以太网首部+IP首部+TCP首部+用户数据
- UDP长度:用户数据报的长度,最小值是8(仅有首部),注意,需要包括数 据的长度
- UDP校验和:把头部和数据加上一起校验
- 1.版本:IP协议的版本。通信双方使用过的IP协议的版本必须一致,目前最广泛使用的IP协议版本号为4(即IPv4 ) 2.首部长度:单位是32位(4字节),首部共20个字节,所以是5(5*4=20字节) 3.服务类型:一般不适用,取值为0。前3位:优先级,第47位:延时,吞吐量,可靠性,花费。第8位保留 4.总长度:指首部加上数据的总长度,单位为字节。最大长度为65535字节,因为IP报头的数据内容其实就是TCP报头或UDP报头再加上应用层的数据,所以要确定你是TCP或者UDP以及你的应用层数据后,才能确定总长度。 5.标识(identification):用来标识主机发送的每一份数据报。IP软件在存储器中维持一个计数器,每产生一个数据报,计数器就加1,并将此值赋给标识字段,我们标识为0就行。 6.标志(flag):目前只有两位有意义。标志字段中的最低位记为MF。MF=1即表示后面“还有分片”的数据报。 MF=0表示这已是若干数据报片中的最后一个。标志字段中间的一位记为DF,意思是“不能分片”,只有当DF=0时才允许分片,我们一般把MF,DF都设置成0 7.片偏移:指出较长的分组在分片后,某片在源分组中的相对位置,也就是说,相对于用户数据段的起点,该片从何处开始。片偏移以8字节为偏移单位,我们一般也是设置成0。 8.生存时间:TTL,表明是数据报在网络中的寿命,即为“跳数限制”,由发出数据报的源点设置这个字段。路由器在转发数据之前就把TTL值减一,当TTL值减为零时,就丢弃这个数据报。通常设置为32、64、128,我们可以把它设置成128。 9.协议:指出此数据报携带的数据时使用何种协议,以便使目的主机的IP层知道应将数据部分上交给哪个处理过程,常用的ICMP(1),IGMP(2),TCP(6),UDP(17),IPv6(41) 10.首部校验和:只校验数据报的首部,不包括数据部分。 13.选项:用来定义一些任选项;如记录路径、时间戳等。这些选项很少被使用,同时并不是所有主机和路由器都支持这些选项。一般忽略不计。
- .序列号:本报文段的数据的第一个字节的序号,确认序号:期望收到对方下一个报文段的第一个数据字节的序号
- 头部长度:单位是32位(4字节),首部共20个字节,所以是5(5*4=20字节)
- 保留:占6位,保留为今后使用,目前应置为0
- 紧急URG: 此位置1,表明紧急指针字段有效,告诉系统此报文段中有紧急数据,应尽快传
- 确认ACK: 仅当ACK=1时确认号字段才有效,TCP规定,在连接建立后所有传达的报文段都必须把ACK置1
- 9.推送PSH:当两个应用进程进行交互式的通信时,有时在一端的应用进程希望在键入一个命令后立即就能够收到对方的响应。在这种情况下,TCP就可以使用推送(push)操作,这时,发送方TCP把PSH置1,并立即创建一个报文段发送出去,接收方收到PSH=1的报文段,就尽快地(即“推送”向前)交付给接收应用进程,而不再等到整个缓存都填满后再向上交付
- 10.复位RST: 用于复位相应的TCP连接
- 11.同步SYN: 仅在三次握手建立TCP连接时有效。当SYN=1而ACK=0时,表明这是一个连接请求报文段,对方若同意建立连接,则应在相应的报文段中使用 SYN=1和ACK=1.因此,SYN置1就表示这是一个连接请求或连接接受报文
- 12.终止FIN:用来释放一个连接。当FIN=1时,表明此报文段的发送方的数据已经发送完毕,并要求释放运输连接。
- ICMP是网络层协议,它是IP数据包后面要跟的一个协议,所以在使用时,在它之前要跟IP协议,ICMP最常用的地方就是使用Ping命令时
- ARP协议:通过对方的IP地址获取MAC地址,RARP协议:通过对方的MAC地址获取IP地址
- 混杂模式 1、指一台机器的网卡能够接收所有经过它的数据包,不论其目的地址是否是它。 2一般计算机网卡都工作在非混杂模式下,如果设置网卡为混杂模式需要root权限 linux下设置
- 1、设置混杂模式:ifconfig eth0 promisc 2、取消混杂模式:ifconfig eth0 -promisc
- 完整的数据报:以太网首部 (目的MAC--6字节+源MAC--6字节+数据报类型--2字节=14字节) + IP首部(ipv--4bit+首部长--4bit+服务类型--8bit+总长度--2字节+第二行4字节+三行首--8bit+协议类型--8bit+校验16bit+三行源IP--4字节+四行目的IP--4字节=20字节) +TCP首部(源端口--2字节+目的端口--2字节+其它16字节=20字节)+用户数据
- 上图是以太网头部+ARP头部,: 1.Dest Mac:因为是发广播,所以是fffffff, 3.帧类型:0x0806 4.硬件类型:1(以太网) 5.协议类型:0x0800(IP地址) 6.硬件地址长度(MAC长度):6 7.协议地址长度(IP长度):4 8.OP:1(ARP请求),2(ARP应答),3(RARP请求),4(RARP应答)5.目的以太网地址:0
- 在组建这些数据报时,超过一个字节的,要么一个一个字节的传,如果一次几个字节的传,要注意大小端,比如,帧类型,0x0806,要占两个字节,要么0x08,0x06分两次传
- 原始套接发送数据:ssize_t sendto(int sockid,msg,msg_len,int flags,(struct sockaddr*) &sll,sizeof(sll)),这其中的sll指的是本机的某个网卡,也就要从哪个网卡发出去
- struct sockaddr_ll,这个本机网络接口的结构体,其内部成员有
需要对sll.sll_ifindex赋值,就可使用
- 至于sll_ifindex这个网络接口类型怎么获取,可以通过int ioctl(int fd,int request,void*)函数来获取网络接口地址
- 上图是原始套接发送的整个代码
- ARP(Address Resolution Protocol,地址解析协议) 3、请求方使用广播来发送请求 4、应答方使用单播来回送数据 5、为了在发送数据的时候提高效率在计算中会有一个ARP缓存表,用来暂时存放ip所对应 的MAC,在linux中使用ARP即可查看,在xp中使用ARP -a
- 当主机A和主机B通信时,会先查看arp表中有没有对方的mac地址,如果有则直接通 信即可,如果没有再调用arp协议获取对方mac地址并将其保存在arp表中
- 无用
计算机网络
于 2022-08-15 10:53:15 首次发布