4-网络编程

一、网络

1、网络介绍

1.概念:

​ 将具有独立功能的多台计算机通过通信线路和通信设备连接起来,在网络管理软件及网络通信协议下,实现资源共享和信息传递的虚拟平台

2.学习目的

​ 能够编写基于网络通信的软件或程序,通常来说就是网络编程。

3.要点

​ 网络就是实现资源共享和信息传递的虚拟平台,我们可以编写基于网络通信的程序,比如:后续学习的socket编程web开发等等。

2、IP地址介绍

1.概念

​ IP地址是分配给网络设备上网使用的数字标签,它能够标识网络中唯一的一台设备,好比现实中每个人都有一个手机号。

2.表现形式

​ 有两种表现形式:ipv4 点分十进制

​ ipv6 冒号十六进制

3.作用

​ 通过IP地址找到网络中唯一一台设备,然后可以跟这个设备进行数据通信。

3、ifconfig和ping命令

1.ifconfig命令

​ 查看IP地址命令(ens33)

ipconfig:windows系统查IP地址

2.ping命令

​ ping IP地址 查看网络是否正常(lo)

4、端口和端口号

1.端口的概念

​ 端口是数据传输的通道,每个端口都有一个端口号

2.端口号

​ 操作系统为了统一管理这么多端口而设置的号码,这就是端口号,端口号其实就是一个数字,好比我们现实生活中的门牌号。

范围 0~65535

3.通信流程

​ 通过ip地址找到对应的设备,通过端口号找到对应的端口,然后通过端口把数据给应用程序

4.分类
  • 知名端口号

    ​ 知名端口号是指众所周知的端口号,范围从0到1023,这些端口号一般固定分配给一些服务,比如21端口分配给FTP(文件传输协议)服务25端口分配给SMTP(简单邮件传输协议)服务80端口分配给HTTP服务

  • 动态端口号

    ​ 一般程序员开发应用程序使用端口号称为动态端口号。

    ​ 范围从1024到65535

5、socket介绍

1.概念

​ socket(套接字)是程序之间进行网络通信的工具

2.作用

​ 程序之间网络数据的传输可以通过socket来完成,socket就是程序间网络数据通信的工具。

6、TCP介绍

1、概念

​ 在网络中数据不能随便发送,在发送之前要选择网络传输方式(传输协议)

​ TCP简称传输控制协议,它是一种面向连接的可靠的基于字节流的传输层通信协议

2、通信步骤

创建连接 >>>传输数据>>>关闭连接

3、特点
  1. 面向连接

    通信双方必须先建立好连接才能进行数据的传输,并且双方都会为此连接分配必要资源用来记录连接的状态和信息。当数据传输完成后,双方必须断开此连接,以释放系统资源。

  2. 可靠传输

    • TCP采用发送应答机制
      通过TCP这种方式发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传送成功
    • 超时重传
      发送端发送一个报文之后就会启动定时器,如果指定时间内没有得到应答就会重新发送这个报文段
    • 错误校验
      TCP用一个校验和函数来校验数据是否有错误,在发送和接收时都要计算校验和
    • 流量控制和阻塞管理
      流量控制用来避免发送端发送过快而使得接收方来不及接收

二、TCP 网络应用程序开发

1、编码转换

  • encode 将字符串转化为字节码

  • decode 将字节码转化为字符串

2、TCP客户端程序开发

  1. 创建客户端套接字对象
  2. 和服务端套接字建立连接
  3. 发送数据
  4. 接收数据
  5. 关闭客户端套接字
import socket

if __name__ == "__main__"v
	# 1. 创建客户端套接字对象  AF_INET表示ipv4网址,SOCK_STREAM表示TCP协议
    tcp_client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 2. 和服务端套接字建立连接
    tcp_client_socket.connect(("192.168.209.130", 8080))
    # 3. 发送数据
    tcp_client_socket.send("nihao".encode(encoding="utf-8"))
    # 4. 接收数据  recv阻塞等待数据的接收
    recv_data = tcp_client_socket.recv(1024)
    print(recv_data.decode())
    # 5. 关闭客户端套接字
    tcp_client_socket.close()

3、TCP服务端程序开发

  1. 创建服务端套接字对象
  2. 绑定IP地址和端口号
  3. 设置监听(转换为被动套接字)
  4. 等待接收客户端连接请求
  5. 接收数据
  6. 发送数据
  7. 关闭套接字
import socket

if __name__ == '__main__':
    # 1. 创建服务端套接字对象
    tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 2. 绑定IP地址和端口号
    tcp_serve_socket.bind(("", 8888))
    # 3. 设置监听(转换为被动状态)
    tcp_serve_socket.listen(128)
    # 4. 等待接收客户端连接请求  accpet阻塞等待
    con_socket, ip_port = tcp_serve_socket.accept()
    # 5. 接收数据
    recv_data = con_socket.recv(1024)
    print(recv_data.decode())
    # 6. 发送数据
    con_socket.send("收到".encode())
    # 7. 关闭套接字
    con_socket.close()
    tcp_serve_socket.close()
  • 补充:端口复用

    当进行TCP网络应用程序开发时,端口释放不是即时的,所以要设置端口复用来释放端口

tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)

4、注意点

  1. 当TCP客户端程序想要和TCP服务端程序进行通信的时候必须要先建立连接

  2. TCP客户端程序一般不需要绑定端口号,因为客户端是主动发起建立连接的。

  3. TCP服务端程序必须绑定端口号,否则客户端找不到这个TCP服务端程序。

  4. listen后的套接字是被动套接字,只负责接收新的客户端的连接请求,不能收发消息

  5. 当TCP客户端程序和TCP服务端程序连接成功后, TCP服务器端程序会产生一个新的套接字,收发客户端消息使用该套接字。

  6. 关闭accept返回的套接字意味着和这个客户端已经通信完毕

  7. 当客户端的套接字调用close后,服务器端的recv会解阻塞,返回的数据长度为0,服务端可以通过返回数据的长度来判断客户端是否已经下线,反之服务端关闭套接字,客户端的recv也会解阻塞,返回的数据长度也为0

5、socket的send和recv的原理

1.TCP socket的发送和接收缓冲区

​ 当创建一个TCP socket对象时会有一个发送缓存区接收缓存区

2.send原理刨析

​ 要想发数据,必须得通过网卡发送数据,应用程序是无法直接通过网卡发送数据的,它需要调用操作系统接口,也就是说,应用程序把发送的数据先写入到发送缓冲区(内存中的一片空间),再由操作系统控制网卡把发送缓冲区的数据发送给服务端网卡

3.recv原理刨析

应用软件是无法直接通过网卡接收数据的,它需要调用操作系统接口,由操作系统通过网卡接收数据,把接收的数据写入到接收缓冲区(内存中的一片空间),应用程序再从接收缓存区获取客户端发送的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8OyPvu0f-1604711492777)(C:\Users\lzq\AppData\Roaming\Typora\typora-user-images\image-20200901101802215.png)]

4.小结

​ 不管是recv还是send都不是直接接收到对方的数据和发送数据到对方,发送数据会写入到发送缓冲区接收数据是从接收缓冲区来读取,发送数据和接收数据最终是由操作系统控制网卡来完成

6.TCP服务端开发-多任务版

import socket
import threading


def send_recv(con_socket):
    # 5. 接收数据
    recv_data = con_socket.recv(1024)
    print(recv_data.decode())
    # 6. 发送数据
    con_socket.send("收到".encode())
    # 7. 关闭套接字
    con_socket.close()


if __name__ == '__main__':
    # 1. 创建服务端套接字对象
    tcp_serve_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    tcp_serve_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, True)
    # 2. 绑定IP地址和端口号
    tcp_serve_socket.bind(("", 8888))
    # 3. 设置监听(转换为被动状态)
    tcp_serve_socket.listen(128)
    # 4. 等待接收客户端连接请求  accpet阻塞等待
    while True:
        con_socket, ip_port = tcp_serve_socket.accept()
        t = threading.Thread(target=send_recv, args=(con_socket,))
        t.start()
    tcp_serve_socket.close()

补充

1、三次握手和四次挥手

1)三次握手
  • 第一次握手:客户端发送TCP报文;其中将标记位SYN置1,表示“请求建立新连接;报文序号seq = x(一般为1);随后客户端进入SYN-SENT阶段【客户端发送来连接请求】
  • 第二次握手:服务端接收到客户端的报文后结束listen,并发送一份TCP报文;其中标记位为SYN和ACK,表示"确认客户端报文seq序号有效,服务器收到数据,并同意创建新连接";报文序号seq = y(一般为1);确认号为ack = x + 1(将客户端的报文序号加一作为确认号);服务端进入SYN-RCVD阶段【服务端回复收到请求,同时向客户端发送同意连接的信息】
  • 第三次握手:客户端收到服务器TCP报文,确定数据传输正常,结束SYN-SENT阶段;并返回最后TCP报文,其中标志位ACK,表示"确认收到服务器同意连接的信号"‘;报文序号seq = x + 1,表示收到服务器端的确认号Ack,并将其值作为自己的序号值;确认号为Ack=y+1,表示收到服务器端序号Seq,并将其值加1作为自己的确认号Ack的值;随后客户端进入ESTABLISHED阶段【客户端回复收到服务器同意连接的信息】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iMSeU3Vs-1604711492779)(C:\Users\lzq\AppData\Roaming\Typora\typora-user-images\image-20200901195811057.png)]

2)四次挥手
  • 第一次挥手:主机1(可以是客户端,也可以是服务器端),设置SeqAck向主机2发送一个FIN报文段;此时,主机1进入FIN_WAIT_1状态;这表示主机1没有数据要发送给主机2了;【客户端发送断开连接请求】
  • 第二次挥手:主机2收到了主机1发送的FIN报文段,向主机1回一个ACK报文段Ack为Seq加1;主机1进入FIN_WAIT_2状态;主机2告诉主机1,我也没有数据要发送了,可以进行关闭连接了;【服务器收到客户端的请求并回复收到,客户端单向断开连接】
  • 第三次挥手:主机2向主机1发送FIN报文段,请求关闭连接,同时主机2进入CLOSE_WAIT状态;【当数据全部传输完成后,服务器向客户端发送断开连接请求】
  • 第四次挥手:主机1收到主机2发送的FIN报文段,向主机2发送ACK报文段,然后主机1进入TIME_WAIT状态;主机2收到主机1的ACK报文段以后,就关闭连接;此时,主机1等待2MSL后依然没有收到回复,则证明Server端已正常关闭,那好,主机1也可以关闭连接了。【客户端向服务器回复同意请求以让服务器断开连接,同时客户端会等待MSL来确保服务端收到信息】

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3UoRNBMT-1604711492780)(C:\Users\lzq\AppData\Roaming\Typora\typora-user-images\image-20200901195655334.png)]

2、os模块

1)文件查询
os.lisdir()
# [文件1, 文件2, ......]

os.path.getsize()
# 获取指定文件大小

os.path.exists()
# 判断指定文件是否存在

收到回复,则证明Server端已正常关闭**,那好,主机1也可以关闭连接了。【客户端向服务器回复同意请求以让服务器断开连接,同时客户端会等待MSL来确保服务端收到信息】

[外链图片转存中…(img-3UoRNBMT-1604711492780)]

2、os模块

1)文件查询
os.lisdir()
# [文件1, 文件2, ......]

os.path.getsize()
# 获取指定文件大小

os.path.exists()
# 判断指定文件是否存在
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值