网络编程套接字

一,基础知识

1.源目标地址和目的地址
源目标地址:指明了此数据包是由哪个IP发送出来的。
目的IP地址 :指明了此数据包的目的地址是哪个IP。
2.端口号
端口号是传输层协议的内容。
(1)端口号是一个2字节16位的整数
(2)端口号用来标识唯一一个网络进程,告诉操作系统,当前这个数据要交给哪一个进程来进行处理。
(3)IP地址+端口号能够标识网络上某一个主机的某一个进程。
(4)一个端口号只能被一个进程占用。
3.pid也标识一个进程,端口号也标识一个进程,两者有什么区别?
区别:就像是一个学生既有身份证号,又有学号是一样的。
端口号用来标识本主机上唯一一个网络进程。
pid是操作系统对进程的一个标识。
公网IP用来标识互联网中唯一一台主机。
4.源端口号和目的端口号
源端口号标识发起通信的那个进程
目的端口号标识接受通信的那个进程。

二,TCP协议和UDP协议

1.概念:
(1)TCP/IP(Transmission Control Protocol/Internet Protocol) 即传输控制协议/网间协议,是一种面向连接(连接导向)的、可靠的、基于字节流的运输层(Transport layer)通信协议。–》买东西,网上支付会用到它。

有连接,可靠传输,面向字节流
(2)UDP协议全称是用户数据报协议,在网络中它与TCP协议一样用于处理数据包,是一种无连接的协议。在OSI模型中,在第四层——传输层,处于IP协议的上一层。UDP有不提供数据包分组、组装和不能对数据包进行排序的缺点,也就是说,当报文发送之后,是无法得知其是否安全完整到达的。—》看视频,直播
无连接,不可靠传输,面向数据报

三,网络字节序

1.关于计算机组成原理中的中断
想问一下,假如计算机中没有中断,比如我们键盘打字,有中断的时候,这些字符转进入缓存区,发生中断再让CPU执行,如果没有中断是不是CPU就会一直等待我们输入,每输入一个CPU就会去执行?

假如你输入的同时又有其他程序要执行呢?那CPU怎么办呢?没有中断处理的情况下
如果不设置中断允许,那么有两种可能性:所有中断请求都屏蔽,或所有中断请求都响应。假如是第一种,那不用说,中断就没有意义了。假如是第二种,那么会产生一个响应先后问题,即如果多个中断同时到达,该按照什么样的顺序去处理的问题。这就会产生一个概念叫中断优先级。优先级高的中断优先响应,如掉电中断,必须立即无条件响应。优先级低的中断,等到CPU处理完高优先级中断并恢复现场后,再响应。控制优先级的手段就是中断允许寄存器。如果CPU判断某个中断处于低优先级,就会屏蔽该中断的IRQ位,此时即使该设备中断到来,也不会响应。直到更高优先级的中断完毕后,再恢复被屏蔽的中断,就可以重新接受响应。

大端:高位数据放在低地址。
小端:高位数据放在高地址。

2.网络数据中同样有大小端之分,那么如何定义网络数据流中的地址呢?
(1)发送主机通常将发送缓冲区中的数据按内存地址从低到高的顺序发出。
(2)接受主机把网络中上接到的字节一次保存到接受缓存区中,也是按照内存地址从低到高的顺序进行缓存。
(3)因此网络数据流的地址应该这样规定,先发的数据是低地址,后发的数据是高地址。
(4)TCP/IP协议规定,网络数据流应该采用大端字节序,即低地址高字节。
(5)不管这台主机是大端机还是小端机,都会按照TCP/IP这个规定来进行接收/发送数据。
(6)如果当前发送主机是小端,就要将数据转化成大端,否则就忽略,直接发送即可。

4.socket编程接口

//创建socket文件描述符(TCP/UDP客户端 + 服务器)
int socket(int domain,int type,int protocol);
域AF_INET  --------   sock_DGRAM 数据报

//绑定端口号(TCP/UDP客户端 + 服务器)
int bind(int socket,const struct socketaddr* address,socklen_t address_len);

//开始监听socket(TCP,服务器)
int listen(int socket,int backlog);

//接受请求(TCP,服务器)
int accept(int socket,struct sockaddr* address.socklen_t* address_len);

//建立连接(TCP,服务器)
int connect(int sockfd,const struct sockaddr* addr,socklen_t addrlen);

为什么进程退出之后,内存泄漏问题不在了?
答案:进程退出时,程序会自动释放资源,但是在服务器上内存泄漏,会有很大的影响,因为服务器需要一直循环,不退出。

客户端不绑定端口号,而服务器要绑定端口号?
答案:一个端口号只能被一个进程使用,当有很多个进程的时候,就不能绑定端口号,要不然其他的进程就无法访问;服务器要被很多客户端知道,服务器的端口号是确定的。

5.TCP/IP协议的流程

1.服务器初始化:
(1)调用socket,创建文件描述符。
(2)调用bind,将文件描述符和ip/port绑定在一起,如果这个接口已经被其他进程占用了,就会bind失败。
(3)调用listen,声明当前文件描述符作为一个服务器文件描述符,为后面的accept做准备。
(4)调用accept,并阻塞,等待客户端链接。
2.建立连接的过程:三次握手
(1)调用socket接口,创建文件描述符。
(2)调用connect,向服务器发起连接请求。
(3)connect会发出SYN段并阻塞等待服务器应答(第一次)。
(4)服务器收到客户端的SYN,回应答一个SYN-ACK段表示“同意建立连接”(第二次)。
(5)客户端收到SYN-ACK后会从connect()返回,同时应答一个ACK(第三次)。
3.为什么称它位三次握手而不是一次或者两次握手?
答案:

TCP的核心思想是,既要保证数据可靠传输,又要保证传输的效率。而三次恰好可以满足这两方面的需求。三次握手目的在于同步连接双方的序列号和确认号并交换 TCP窗口大小信息,让双方都确认自己发送的信息对方能够收到。这样三次就足够了,四次效率低且浪费资源。

一次握手不行的原因是:服务器会认为客户端送的第一个SYN请求报文段丢失,客户端会持续发送链接,服务器认为恶意攻击。

两次握手不行的原因是:client认为发送的第一个SYN请求报文段丢失,然后发起第二个SYN,如果是两次握手,server端回应后连接就建立了。然而client发出的第一个SYN请求报文段并没有丢失,而是在某个网络节点长时间滞留了,以致延误到client-server连接释放以后它才到达了server。本来这是一个早已失效的报文段,但server收到此失效的连接请求报文段后,就误认为client再次发出一个新连接请求。于是就向client发出确认报文段,同意建立连接。在两次握手的情况向,这时新的连接就建立了。但是client实际上并没有发出建立连接的请求,因此并不会理睬server的确认,也不会像server发送数据。但server却单方面认为连接已经建立,就开始一直等待client发送数据。这样,server的资源就白白浪费掉了。采用”三次握手”的办法可以防止上述现象发生。
总结:数据丢失,
数据发送的时候,服务器认为建立连接,客户端认为没有建立链接,会使服务器挂起很多连接,资源浪费。
4.数据传输的过程:
(1)建立连接后TCP协议提供全双工的通信服务(在同一条连接上,同一时刻,通信双方可以同时写数据)
(2)服务器从accept()返回之后立刻调用read(),读socket就像读管道一样,如果没有数据到达就阻塞等待。
(3)这时客户端调用write()发送数据给服务器,服务器收到后从read()返回,对客户的请求进行处理。(在此期间,客户端调用read()阻塞等待服务器的应答)。
(4)服务器调用write()将数据处理结果发给客户端,再次调用read()阻塞等待下一个请求。
(5)客户端收到后从read()返回,发送下一条请求。
5.断开连接的过程:四次挥手
(1)如果客户端没有更多的请求了,就调用close()接口关闭连接,客户端会向服务器发送FIN段(第一次)。
(2)此时服务器收到FIN之后,会回应一个ACK,同时read会返回0(第二次)。
(3)read返回之后,服务器就知道客户端关闭了连接,也调用close关闭连接,这个时候服务器会向客户端发送一个FIN(第三次)。
(4)客户端收到FIN,再返回一个ACK给服务器(第四次)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值