「Python网络编程」进入网络通信编程的大世界(一)

博主前言:

寒假在家待着实属无聊,所以准备继续跟博,本来想搞一个什么“十天搞定Python网络编程”、“一周Python网络编程入门大法”等等,但是在整理完资料开始写的时候才发现这些搏眼球的招数都被全网用遍了,倒不如实实在在写一些东西。开写网络编程系列呢,需要读者已经了解了Python语言的语言逻辑和具有使用Python编程的基础,这方面的知识网上也挺多的,所以博主来这里就不在继续讲解,如果有地方不懂的可以留言,我会及时的回复哒。

1. 几个网络编程重要概念

1.1 IP地址

首先我们要知道网络编程的目的是为了进行通信,所以IP地址可以理解为不同电脑在网络中的标识定位,只有知道IP地址才能准确的定位对方的电脑进行通信。

1.1.1 IP地址的分类

IP地址分为两大类:IPv4IPv6
其中IPv4又分为A、B、C、D、E五类地址。

A类地址:0 + 网络号7位 + 主机号24位
B类地址:10 + 网络号14位 + 主机号16位
C类地址:110 + 网络号21位 + 主机号8位
D类地址:保留地址,网络号由1110开头
E类地址:保留地址,网络号由11110开头

其中主机号全是0和全是1的地址用不了,所以一个C类地址的IP地址,网络号确定时,其最多定义254台电脑。
最后注意:IP地址为127.0.0.1127.255.255.255用于回环测试

1.2 端口号

端口号是用来标识进程的值。这里引入的一个进程的概念,很简单,所谓进程就是运行着的程序,我们打开任务管理器,如图所示。
这里为什么我们用进程,而不是程序呢,因为在列表中都是运行着的程序啦。很简单吧。
在这里插入图片描述
如果把IP地址比作你家的房子的地址,那端口号就是你家里的成员的名字。当发生网络通信的时候,通过你家的地址,找到你家,然后通过你们家里人的名字确认与家里的谁进行通信。也就是,通过IP地址确认主机电脑,再通过端口号确认与电脑里哪一个程序进行通信的过程。
我们再来了解两个关于端口号的概念。

1.2.1 端口号的分类

第一类叫知名端口,又称周知端口,两个词指的是同一个概念,即值从0~1023的端口号,共1024个端口号。这些端口号都被预先使用了,我们编写程序是不能使用的,所以叫做知名端口或周知端口。例如:端口号为80指的HTTP服务;端口号为21指的FTP服务等
第二类叫动态端口,即值从1024~65535的端口号。动态端口,顾名思义,其值是动态分配的。当我们开发一个程序时,其端口号值由开发者去绑定。亦或当开发者没有绑定时,系统默认给你动态分配一个值,例如QQ。

2. 套接字Socket模块

Socket是进程间通信的一种方式,可以实现不同主机间的进程间通信。众所周知,网络通信有两种方法,一种是基于TCP协议的通信方法,另一种是基于UDP协议的通信方法。所以Python的Sockert模块针对两种不同的方法有两种说明。接下来我们就let it down,开始我们迷人又可爱的编程!

2.1 创建一个UDP Socket

import socket
def main():
    # 建立udp对象,第一个参数是 使用ipv4协议 第二个参数是 使用 udp 协议
    udp_socket = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    # 绑定一个端口号
    localaddr = ("",1314)
    udp_socket.bind(localaddr)
    # 输入你想发送的数据
    send_Data = "给你1个G"
    # 发送数据,以 udp 的方式,第二参数是一个元组,包含目标ip和端口号
    udp_socket.sendto(send_Data.encode("utf-8")("127.0.0.1",6666))
    print("发送成功!")
    # 关闭套接字
    udp_socket.close()
if __name__ =='__main__':
    main()

通过上面的代码我们就实现了创建一个基于UDP协议的Socket对象,并进行向IP地址为“127.0.0.1”(回环测试),端口号为6666的程序发送数据。
首先,我们用socket模块的构造方法创建一个UDP对象,构造方法中有两个参 数,第一个参数代表使用IPv4协议,第二个参数代表使用UDP协议。
然后,我们将创建好的Socket对象绑定一个端口号,使用bind函数,函数第一个参数是IP地址,默认为本机的任一IP地址,第二个参数为端口号。
接着,我们调用sendto函数,向目的IP地址及端口发送数据,发送函数的第一个参数为发送的数据,其类型为bytes类型,其中我们选择使用utf-8的格式进行编码,第二个参数为一个元组类型,其包含了目的主机的IP地址和目的程序的端口号。
最后,调用close函数,关闭套接字。

我们使用网络调试助手模拟上述步骤,将在网络调试助手的界面得到以下图示。
在这里插入图片描述

2.2 创建一个TCP Socket

TCP通信模型相比UDP通信模型更加稳定,可靠。因为TCP通信模型在数据发送之前有创建连接的步骤(俗称:三次握手),并在数据发送阶段有ACK、超时重传(RTT)、错误校验、流量控制和阻塞管理等加强通信模型可靠性的措施,所以TCP通信模型运用得更加普遍。

import socket
def main():
    # 1.创建 tcp 套接字
    tcp_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    # 2.链接服务器
    tcp_socket.connect(("127.0.0.1",1314))
    # 3.发送数据
    data = input("Input the data what you want to send:")
    tcp_socket.send(data.encode("utf-8"))
    # 4.关闭套接字
    tcp_socket.close()

if __name__ == '__main__':
    main()

同样,我们通过上述代码创建了一个基于TCP的Socket对象,并与IP地址为“127.0.0.1”,端口号为1314的服务器程序进行链接。然后通过input函数从键盘上获得需要发送的数据,并调用send函数以utf-8的格式发送数据,最后关闭套接字。

在这里不禁提出一个问题,在创建UDP Socket对象时,我们还调用了bind函数,绑定一个IP地址和端口号,为什么在创建TCP Socket对象的时候,我们没有使用bind函数去绑定呢?使用bind函数是必须的吗?

我们再次利用网络调试助手进行步骤演示,以网络调试助手为服务器,代码运行作为客户端。在这里插入图片描述代码运行客户端
我们从对端口号的学习中知道,当开发者没有绑定端口号,程序运行时,系统会默认给它分配一个动态端口用以通信,例如上图网络调试助手中的51383,就是系统为此进程默认分配的动态端口。所以,当确认程序只进行发送操作而不进行接收操作时,程序可以不进行绑定操作,但是若程序需要进行接收操作时,没有绑定端口号,发送方将无法得知接收方的地址,无法成功进行接收操作。

好了,第一篇算是完成了,其中干货也是满满呀,希望读者好好消化吸收,如果有不懂的地方一定留言交流,想想下一篇写什么呐?多线程?

发布了4 篇原创文章 · 获赞 4 · 访问量 205

猜你喜欢

转载自blog.csdn.net/qq_43462005/article/details/104024694