Linux网络通信

01_socket套接字

是一个能够在多个系统(x86、unix、Linux)下运行的一组API接口,不仅仅只能跑tcp/ip协议,既可以网络通信,也可以IPC通信(计算机内部通信)。

01_01套接字类型

1.流式套接字(SOCK_STREAM):提供了一个面向连接、可靠的数据传输服务,
数据无差错、无重复的发送且按发送顺序接受。内设置流量控制,避免数据流淹没慢的接收方。数据被看作是字节流,无长度限制。针对TCP
2.数据报套接字(SOCK_DGRAM)
提供无连接服务。数据包以独立数据包的形式被发送,不提供无差错服务保证,数据可能丢失或重复,顺序发送,可能乱序接受。针对UDP
3.原始套接字(SOCK_RAW)

可以对较低层次协议如IP、ICMP直接访问。(ping、traceroute使用该协议)


01_02socket网络编程在网络协议的位置

01_02_01 OSI理想化模型分层

OSI 7 层模型(理想化模型): 物理层、数据链路层、网络层、传输层、会话层、表示层、应用层

 01_02_02 TCP/IP模型

tcp/ip4层模型:

1)应用层 常见的协议有HTTP协议,FTP协议。

2)传输层 常见协议有TCP/UDP协议。

3)网络层 常见协议有IP协议、ICMP协议、IGMP协议。

4)网络接口物理层 常见协议有ARP协议、RARP协议。

注:

HTTP超文本传输协议(Hyper Text Transfer Protocol)是互联网上应用最为广泛的一种网络协议。 ​

FTP文件传输协议(File Transfer Protocol)

IP协议是因特网互联协议(Internet Protocol)

TCP传输控制协议(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。

UDP用户数据报协议(User Datagram Protocol)是OSI参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务。

ICMP协议是Internet控制报文协议(Internet Control Message Protocol)它是TCP/IP协议族的一个子协议,用于在IP主机、路由器之间传递控制消息。 ​

IGMP协议是 Internet 组管理协议(Internet Group Management Protocol),是因特网协议家族中的一个组播协议。该协议运行在主机和组播路由器之间。

ARP协议是正向地址解析协议(Address Resolution Protocol),通过已知的IP,寻找对应主机的MAC地址。 ​

RARP是反向地址转换协议,通过MAC地址确定IP地址。

在tcp/ip中socket的位置:是传输层和应用层中的一个抽象层API接口

02_TCP服务器端流程 

02_01什么是服务器

我们使用应用程序有两种模型。b/s模型(Browser/Server) c/s模型(client/server)

C/S :传统的网络应用设计模式,客户机(client)/服务器(server)模式。需要在通讯两端各自部署客户机和服务器来完成数据通信。

B/S  :浏览器(Browser)/服务器(server)模式。只需在一端部署服务器,而另外一端使用每台PC都默认配置的浏览器即可完成数据的传输。

选用C/S模型的优点:   1. 协议选用灵活。  (可以在标准协议的基础上根据需求裁剪及定制。例如,腾讯公司所采用的通信协议,即为ftp协议的修改剪裁版。)

02_02 API函数

流程中的API函数全部是系统调用,即是操作系统(Linux内核)中的,无需程序员自己去写。下面逐个介绍。

socket() 创建套接字

bind() 绑定本机地址和端口

connect() 建立连接

listen() 设置监听套接字上限 

accept() 接受TCP连接

recv(), read(), recvfrom() 数据接收

send(), write(), sendto() 数据发送

close(), shutdown() 关闭套接字

1.socket

int socket(int domain, int type, int protocol);
        domain参数一:
            AF_INET 这是大多数用来产生socket的协议,使用TCP或UDP来传输,用IPv4的地址
            AF_INET6 与上面类似,不过是来用IPv6的地址
            AF_UNIX 本地协议,使用在Unix和Linux系统上,一般都是当客户端和服务器在同一台及其上的时候使用
        type参数二,01_01已经介绍套接字的类型:
            SOCK_STREAM 这个协议是按照顺序的、可靠的、数据完整的基于字节流的连接。这是一个使用最多的socket类型,这个socket是使用TCP来进行传输。
            SOCK_DGRAM 这个协议是无连接的、固定长度的传输调用。该协议是不可靠的,使用UDP来进行它的连接。
            SOCK_RAW socket类型提供单一的网络访问,这个socket类型使用ICMP公共协议。(ping、traceroute使用该协议)
        protocol参数三:
            传0 表示使用默认协议。 

返回值:

        成功:返回指向新创建的socket的文件描述符,失败:返回-1,设置errno

2.bind

int bind(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
        sockfd参数一:
            socket文件描述符
        addr参数二:
            构造出IP地址加端口号
        addrlen参数三:
            sizeof(addr)长度

返回值:

        成功返回0,失败返回-1, 设置errno

注意:参数二是结构体类型,成员变量有IP和PORT,参数二传入初始化后的指针,例如:

        struct sockaddr_in servaddr;
        servaddr.sin_family = AF_INET;
        servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
        servaddr.sin_port = htons(6666);

其中地址类型为AF_INET,网络地址为INADDR_ANY,这个宏表示本地的任意IP地址,因为服务器可能有多个网卡,每个网卡也可能绑定多个IP地址,这样设置可以在所有的IP地址上监听,直到与某个客户端建立了连接时才确定下来到底用哪个IP地址,端口号为6666。参数二传入&servaddr即可。

3.listen

int listen(int sockfd, int backlog);
        sockfd:
            socket文件描述符
        backlog:
            要监听的套接字的上限

返回值:成功返回0,失败返回-1。

有许多客户端要连接,因accept一次循环处理一个客户端,其他客户端是待连接状态,listen设置待连接状态的客户端数量,收到更多的连接请求就忽略。

4.accept

int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);
        sockdf:
            socket文件描述符
        addr:
            传出参数,返回链接客户端地址信息,含IP地址和端口号
        addrlen:
            传入传出参数(值-结果),传入sizeof(addr)大小,函数返回时返回真正接收到地址结构体的大小

返回值:

        成功返回一个新的socket文件描述符,用于和客户端通信,失败返回-1,设置errno

accept函数整个是一个while死循环,每次循环处理一个客户端连接。

5.connect

int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
        sockdf:
            socket文件描述符
        addr:
            传入参数,指定服务器端地址信息,含IP地址和端口号
        addrlen:
            传入参数,传入sizeof(addr)大小
        返回值:
            成功返回0,失败返回-1,设置errno

02_03c/s服务器和客户端搭建流程

  1. c/s 服务器搭建流程:
    1. 创建套接字 :socket

    2. 绑定ip和端口 :bind

    3. 建立监听 :listen

    4. 接收/处理客户端连接请求 :accept

    5. 正常通信

      1. read/recvfrom/recv

      2. write/sendto/send

    6. 通信完毕,关闭套接字

  2. c/s客户端搭建流程:
    1. 创建套接字:socket

    2. 绑定:bind<可选>,默认隐式绑定

    3. 主动连接服务器:connect

    4. 正常通信

      1. read/recvfrom/recv

      2. write/sendto/send

    5. 通信完毕,关闭套接字

 

03_ 以太网头、ip头、tcp头

03_01以太网头

以太网是网络接口物理层的,MAC地址是网卡,即48位全球唯一,网络设备的身份标识

 以太网包头(MAC Header)前6个字节是目的MAC地址,接着六个字节是源MAC地址,后两个字节是网卡类型:0x08C0 IPV4,0x86DD IPV6,0x08C6 ARP(正向地址解析协议,由IP地址找到MAC地址),0x80f3(反向地址解析协议,由MAC地址找到IP)

发送

03_02ip头 

ip地址占4个字节

12-15字节:源ip地址

16-19字节:目的ip地址

4-5字节,5-5.75,5.75-7字节先不管

0-0.5字节:IP版本——IPv4/IPv6

0.5-1字节: 头部长度——20字节/24字节

1字节:服务类型,贵的会好一些,这里忽略

2-3字节:总长度:最多2的16次方——16KB

8字节:生命周期,超时则丢包

9字节: 下一层的传输层协议是UDP或TCP

10-11字节: CRC校验16位

 03_03tcp头

0-1字节:源端口

2-3字节:目的端口

4-7字节:序列号

8-11字节:确认序列号

12-12.5字节:tcp头到data之间的偏移

12.5-13字节:预留

13字节:TCP标志

14-15字节:数据窗

16-17字节:16位CRC校验位

18-19字节:紧急指针(OOB)

20-24字节:TCP可选项

 IP协议和TCP协议都有差错处理(含有CRC检验),但是第三层的IP协议和第四层的以太网协议都是不可靠的。TCP协议是可靠的,TCP把所有要发送的数据进行编号〈每一个字节用一个号),而且它有确认和重发机制:

发送数据包时,假设有100K数据要发,每个包有1k即1024个字节,数据窗就是1023(发送时从当前数据位置,发送window大小的数据),序列号SYN=1023,如果接收端收到数据,标志位就变为A 0x10 Ack,确认序列号ACK变为1024:这代表了①前面1023个字节都收到②请从1024号开始分配。这里确认序列号和序列号之间进行了确认,如果对不上,就重新发送,这就是确认和重发机制。

03_04TCP/IP协议网络封包和拆包

封包格式:

一次性最多只能发送1500字节个数据(1k多一点),那么传送100k的数据如果一个包1k就需要来连续的100个TCP包,

拆包如下,跟tcp头有关:

上面ip头、4-23字节用于拆包

4-5字节:设置每个包的id

5-5.75字节:0x40 D没有碎片化,0x20 M更多碎片化。如果后面还有包,设置M=1,如果是                          最后一个包设置D=1

5.75-7字节:每个包当前的偏移,第二个开头应该是1024(写成1000了)

03_05TCP协议优势

TCP是一种面向连接的,可靠的数据传输

①TCP的可靠传输:通过确认和重发机制

1.TCP把所有要发送的数据进行编号〈每一个字节用一个号)

2.发送时从当前数据位置,发送window大小的数据

②TCP是面向连接的:TCP三次握手,四次挥手

过程就像互相发一次数然后确认,客户端向服务器发送SYN=j序列号,服务器端回应ACK=j+1,和序列号SYN=k ,客户端回应ACK=k+1

 这里四次挥手区分 一个字节的标志位ACK和FIN,和四个字节的序列号和确认序列号seq,ack

 

因为有time_wait(30s-2min),断开连接后不能马上连接,需要在服务器端设置地址快速重用

int b_reuse = 1;
setsockopt (fd,SOL_SOCKET,SO_REUSEADDR,&b_reuse,sizeof (int)) ;

 

  • 30
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值