python_网络编程(TCP/IP协议、套接字)

网络通信协议概述

1、 什么是网络?

简单意义上来说,网络就是⼀种辅助双⽅或者多⽅能够连接在⼀起的⼯具。

官方对于网络的定义为:
网络是由若干节点和连接这些节点的链路构成,表示诸多对象及其相互联系。

在1999年之前,人们一般认为网络的结构都是随机的。但随着Barabasi和Watts在1999年分别发现了网络的无标度和小世界特性并分别在世界著名的《科学》和《自然》杂志上发表了他们的发现之后,人们才认识到网络的复杂性。 [1]

网络会借助文字阅读、图片查看、影音播放、下载传输、游戏、聊天等软件工具从文字、图片、声音、视频等方面给人们带来极其丰富的生活和美好的享受。

2、使用网络的目的?

联通多⽅然后进⾏通信⽤的,即把数据从⼀⽅传递给另外⼀⽅。

  • ⽤⽹络能够把多⽅链接在⼀起,然后可以进⾏数据传递

  • ⽹络编程就是,让在不同的电脑上的软件能够进⾏数据传递,即进程之间的通信,如下图:
    在这里插入图片描述

TCP/IP协议

通信网络协议是什么?

网络通信协议是一种网络通用语言,为连接不同操作系统和不同硬件体系结构的互联网络引提供通信支持,是一种网络通用语言。
例如,网络中一个微机用户和一个大型主机的操作员进行通信,由于这两个数据终端所用字符集不同,因此操作员所输入的命令彼此不认识。为了能进行通信,规定每个终端都要将各自字符集中的字符先变换为标准字符集的字符后,才进入网络传送,到达目的终端之后,再变换为该终端字符集的字符。因此,网络通信协议也可以理解为网络上各台计算机之间进行交流的一种语言。

常见的网络通信协议有:TCP/IP协议、IPX/SPX协议、NetBEUI协议等
问题: 不同种类之间的计算机到底是怎么进⾏数据传递的呢?
就像说不同语⾔的⼈沟通⼀样,只要有⼀种⼤家都认可都遵守的协议即可, 那么这个计算机都遵守的⽹络通信协议叫做 TCP/IP协议
在这里插入图片描述

TCP/IP协议族

TCP/IP(Transmission Control Protocol/Internet Protocol,传输控制协议/网际协议)是指能够在多个不同网络间实现信息传输的协议簇。TCP/IP协议不仅仅指的是TCP 和IP两个协议,而是指一个由FTP、SMTP、TCP、UDP、IP等协议构成的协议簇, 只是因为在TCP/IP协议中TCP协议和IP协议最具代表性,所以被称为TCP/IP协议。
在这里插入图片描述
OSI模型共有七层分别为,物理层、数据链路层、网络层、传输层、会话层、表示层、应用层
TCP/IP将OSI模型简化为四层:网络接口层、网络层、传输层、应用层
每一层对应的协议有:

  • 网络接口层协议:Ethernet 802.3、Token Ring 802.5、X.25、Frame relay、HDLC、PPP ATM等。
  • 网络层协议:IP(Internet Protocol,英特网协议)、ICMP(Internet Control Message Protocol,控制报文协议)、ARP(Address Resolution Protocol,地址转换协议)、RARP(Reverse ARP,反向地址转换协议)。
  • 传输层协议: TCP(Transmission Control Protocol,传输控制协议)和UDP(User Datagram protocol,用户数据报协议)。
  • 应用层协议:FTP(File Transfer Protocol,文件传输协议)、TELNET(用户远程登录服务协议)、DNS(Domain Name Service,是域名解析服务)、SMTP(Simple Mail Transfer Protocol,简单邮件传输协议)、NFS(Network File System,网络文件系统)、HTTP(Hypertext Transfer Protocol,超文本传输协议)。

IP地址

ip地址:⽤来在⽹络中标记⼀台电脑的⼀串数字,⽐如192.168.1.1;在本地局域⽹上是唯一的。
在这里插入图片描述
IP地址的分类:
每⼀个IP地址包括两部分:⽹络地址和主机地址
在这里插入图片描述
私有IP
⽹络IP中,国际规定有⼀部分IP地址是⽤于局域⽹使⽤,也 就是属于私⽹IP,不在公⽹中使⽤的,它们的范围是:
10.0.0.0~10.255.255.255
172.16.0.0~172.31.255.255
192.168.0.0~192.168.255.255

回环地址IP
IP地址127.0.0.1 代表本机IP地址,等价于localhost, ⽤ http://127.0.0.1 就可以测试本机中配置的Web服务器。
127.0.0.1,通常被称为本地回环地址(Loop back address),不属于任何一个有类别地址类。它代表设备的本地虚拟接口,所以默认被看作是永远不会宕掉的接口。在windows操作系统中也有相似的定义,所以通常在不安装网卡前就可以ping通这个本地回环地址。一般都会用来检查本地网络协议、基本数据接口等是否正常的。

⼦⽹掩码
⼦⽹掩码不能单独存在,它必须结合IP地址⼀起使⽤。
⼦⽹掩码的作⽤: 将某个IP地址划分成⽹络地址和主机地址两部分. ⼦⽹掩码的设定 必须遵循⼀定的规则, 用来判断两个IP是否在同一个网络。
A: 172.25.254.18/24
B: 172.25.0.10/24

端口

  • 端⼝就好⼀个房⼦的⻔,是出⼊这间房⼦的必经之路。
  • 端⼝号只有整数,范围是从0到65535;
    请说说你知道的服务及对应的端口号。
    ftp服务的端口是21
    http服务的端口是80
    https服务的端口是443
    ssh服务的端口是22
    mysql服务的端口是3306
    可以通过netstat -antlupe | grep 服务名 来查询服务的端口号
服务名端口号
HTTP80
FTP21
SSH22
Telnet23
SMTP25
HTTPS443
POP2109
POP3110
DHCP Client546
DHCP Server547
MSN569
SSL990
IMAP993
Worm.Sasser.e1023
sqlserver1433
Oracle1521
MySql3306

在命令行输入:cat /etc/services | less 即可查看所需要的查看的服务的端口。(当然,前提是你的主机安装了你所要查询的服务才能够查询到)
比如:查看http服务的端口:命令行输入:cat /etc/services | less (可以查看规定好的服务对应的端口号)

在这里插入图片描述

在这里插入图片描述

socket编程

⽹络进程间通信
问题: 本地通过进程PID来唯⼀标识⼀个进程,在⽹络中如何唯⼀标识⼀个进程?
⽹络层的“IP地址”可以唯⼀标识⽹络中的主机,⽽传输层的“协议+端⼝”可以唯⼀标识主机中的应⽤程序(进程)。因此利用IP地址协议,端⼝就可以标识⽹络的进程。

什么是socket?
socket(简称套接字) 是进程间通信的⼀种⽅式, 能实现不同主机间的进程间通信,我们⽹络上各种各样的服务⼤多都是基于 Socket 来完成通信的。
套接字(socket)是一个抽象层,应用程序可以通过它发送或接收数据,可对其进行像对文件一样的打开、读写和关闭等操作。套接字允许应用程序将I/O插入到网络中,并与网络中的其他应用程序进行通信。网络套接字是IP地址与端口的组合。

在这里插入图片描述
创建socket
在 Python 中 使⽤socket 模块的函数 socket 就可以完成:

socket.socket(AddressFamily, Type)

1). Address Family:

AF_INET: IPV4⽤于 Internet 进程间通信 AF_INET6: IPV6⽤于 Internet 进程间通信

2). Type:套接字类型

SOCK_STREAM: 流式套接字,主要⽤于 TCP 协议 SOCK_DGRAM: 数据报套接字,主要⽤于 UDP 协议

import socket
# 创建socket对象
#       family:AF_INET(IPV4)    AF_INET6(IPV6) ===>网络层协议
#       type: #SOCK_STREAM(TCP)  SOCK_DGRAM(UDP) ===>传输层协议
# linux中可以认为socket是一个文件
socketobj = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)

print(socketobj.getsockname())
import os
print(os.system('hostname'))
hostname = socket.gethostname()
print(hostname)
print(socket.gethostbyname('localhost'))
socketobj.close()# 关闭socket对象

在这里插入图片描述

UDP介绍

什么是UDP?
UDP ⽤户数据报协议,是⼀个⽆连接的简单的⾯向数据报的运输层协议。UDP不提供可靠性,它只是把应⽤程序传给IP层的数据报发送出去,但 是并不能保证它们能到达⽬的地。由于UDP在传输数据报前不⽤在客户和服 务器之间建⽴⼀个连接,且没有超时重发等机制,故⽽传输速度很快。
UDP是⼀种⾯向⽆连接的协议,每个数据报都是⼀个独⽴的信息,包括完整 的源地址或⽬的地址,它在⽹络上以任何可能的路径传往⽬的地,因此能否到达⽬的地,到达⽬的地的时间以及内容的正确性都是不能被保证的。

UDP的特点
UDP是⾯向⽆连接的通讯协议,UDP数据包括⽬的端⼝号和源端⼝号信息, 由于通讯不需要连接,所以可以实现⼴播发送。 UDP传输数据时有⼤⼩限 制,每个被传输的数据报必须限定在64KB之内。 UDP是⼀个不可靠的协 议,发送⽅所发送的数据报并不⼀定以相同的次序到达接收⽅。

  • 一、UDP是无连接的,即通信时不需要创建连接(发送数据结束时也没有连接可以释放)所以减小了开销和发送数据前的时延;

  • 二、UDP采用最大努力交付,不保证可靠交付,因此主机不需要维护复杂的连接状态;

  • 三、UDP是面向报文的,只在应用层交下来的报文前增加了首部后就向下交付IP层;

  • 四、UDP是无阻塞控制的,即使网络中存在阻塞,也不会影响发送端的发送频率

  • 五、UDP支持一对一、一对多、多对一、多对多的交互通信

  • 六、DUP的首部开销小,只有8个字节,它比TCP的20个字节的首部要短。
    在这里插入图片描述
    UDP的应用场景
    UDP是⾯向消息的协议,通信时不需要建⽴连接,数据的传输⾃然是不可靠 的,UDP⼀般⽤于多点通信和实时的数据业务,⽐如:

    • 语⾳⼴播
    • 视频
    • QQ
    • TFTP(简单⽂件传送)
    • SNMP(简单⽹络管理协议)
    • DNS(域名解释)
      UDP通信息过程:
      通过UDP通信服务的过程: 无论是服务端还是客户端,都需要首先建立一个socket()对象将来进行通信,服务端需要绑定一个IP或一个端口。客户端想要给客户端发消息,由于UDP是无连接的,所以客户端不需要通知服务端,直接发送就好了,消息发送之后,服务端优势会做出一个响应回复给客户端,然年后客户端会进行接收,这样一次通信就结束了。当客户端决定 不发消息了,此时就可以结束掉socket()对象了。(当然,如果服务端也不想让别人给发送消息的时候,也可以吧自己的socket()对象结束掉。)图解如下:
      在这里插入图片描述
      在这里插入图片描述
      实验:实现UDP通信
      注意:
      socket默认再传输的时候传输的是bytes类型因此客户端和服务端发送utf-8的数据时要通过encode(‘utf-8’)转换为bytes类型,
      而客户端和服务端接收数据时要把tytes类型的数据通过decode(‘utf-8’)转换为utf-8类型
      服务端:
import socket
# 1.实例化socket对象
updserver = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)

# 2.绑定端口号
# 0.0.0.0 表示开放所有的ip地址
updserver.bind(("0.0.0.0",9009))

print('等待客户端UDP的连接。。。')

# 3.接受客户端连接
recvdata,address = updserver.recvfrom(1024)
print('接受到客户端的数据:',recvdata.decode('utf-8'))

# 4.给客户端回复消息
updserver.sendto(b'hello client',address)

# 5.关闭socket对象
updserver.close()

客户端:

import socket
udpclient = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)
udpclient.sendto(b'hello server',('172.25.254.15',9009))
recvdata,address = udpclient.recvfrom(1024)
print('接收服务器的数据:',recvdata.decode('utf-8'))
udpclient.close()

服务端运行结果:
在这里插入图片描述
客户端运行结果:
在这里插入图片描述
项目案例:使用UDP服务模拟QQ聊天
服务端:

import socket
# 1.实例化socket对象
updserver = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)

# 2.绑定端口号
# 0.0.0.0 表示开放所有的ip地址
updserver.bind(("0.0.0.0",9009))

print('A用户上线。。。')
while True:
    # 3.接受客户端连接
    recvdata,address = updserver.recvfrom(1024)
    print('B:>>',recvdata.decode('utf-8'))
    if recvdata == b'quit':
        print('聊天结束。。。。')
        break
    # 4.给客户端回复消息
    send_data = input('A:>>').encode('utf-8')
    updserver.sendto(send_data,address)
# 5.关闭socket对象
updserver.close()

客户端:

import socket
udpclient = socket.socket(family=socket.AF_INET,type=socket.SOCK_DGRAM)
print('B用户已上线。。。。。')
while True:
    send_data = input('B:>>').encode('utf-8')
    if not send_data:
        continue
    udpclient.sendto(send_data,('172.25.254.15',9009))
    if send_data == b'quit':
        print('聊天结束。。。')
        break
    recvdata,address = udpclient.recvfrom(1024)
    print('A:>>',recvdata.decode('utf-8'))
udpclient.close()

TCP介绍

TCP: 传输控制协议(英语:Transmission Control Protocol,缩写为TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议。
TCP/UDP对比
在这里插入图片描述
TCP通信过程
TCP协议通信的大致过程:首先,服务端和客户端都需要先建立socket()对象——服务端绑定IP和端口——服务端进行监听(为了保证有客户端和服务端进行连接)—— 监听结束如果有客户端和服务端连接,则可允许客户端建立连接(accept())——客户端发出连接信号——服务端读取信号并作出响应,然后回复客户端——以此循环,完成通信,——当双方各或某一方不想再继续通信,则关闭通信。
在这里插入图片描述
TCP代码实现
服务端:


并发服务器

并发服务器是socket应用编程中最常见的应用模型。根据连接方式分为长连接和短连接.

通信方式具体通信过程
长连接建立SOCKET连接后不管是否使用都保持连接
短连接双方有数据交互时,建立TCP连接,数据发送完成后断开连接

并发服务器模型根据处理方式可分为同步方式和异步方式。
在这里插入图片描述
还可分为单进程服务器和多进程服务器
单进程服务器:

同⼀时刻只能为⼀个客户进⾏服务,不能同时为多个客户服务
类似于找⼀个“明星”签字⼀样,客户需要耐⼼等待才可以获取到服务

多进程服务器:
优点:通过为每个客户端创建⼀个进程的⽅式,能够同时为多个客户端进⾏服务
缺点: 当客户端不是特别多的时候,这种⽅式还⾏,如果有⼏百上千个,就不 可取了,因为每次创建进程等过程需要好较⼤的资源


# 实现多进程:实例化对象,创建子类继承

# 任务: 处理客户端的请求并为其服务
def dealwithClient(clientB_socket_obj):
    while True:
        # 接收客户端发送的消息
        recv_data = clientB_socket_obj.recv(1024)
        print('B:', recv_data.decode('utf-8'))  # 发来的是bytes类型,解码成字符串
        if recv_data == b'quit':
            print('聊天结束....')
            break
        # 给客户端发送消息
        send_data = input('A:').encode('utf-8')
        if not send_data:
            continue
        clientB_socket_obj.send(send_data)
    clientB_socket_obj.close()
import socket
from multiprocessing import Process
# 创建socket对象
serverA = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM)
# 绑定地址和端口
serverA.bind(('0.0.0.0', 9996))
# 监听是否有客户端连接
serverA.listen(5)
# 接收多次请求
while True:
    # 4.接收客户端的连接 accept返回两个值:跟服务端交流的socket对象;跟服务端交流的地址
    clientB_socket_obj, client_addres = serverA.accept()
    p = Process(target=dealwithClient, args=(clientB_socket_obj,))
    p.start()

多进程的话服务端会产生报错:
EOFError: EOF when reading a line
在这里插入图片描述
通常会使用多线程达到同样的效果

from threading import Thread
def dealwithclient(clientsocketobj):
    while True:
        # 5.接收客户端发送的消息
        recv_data = clientsocketobj.recv(1024)
        print('客户端接收到的消息为:',recv_data.decode('utf-8'))
        if recv_data == 'quit':
            break
        # 6.给客户端发送消息
        send_data = b'gun'
        if not send_data:
            continue
        clientsocketobj.send(send_data)
    clientsocketobj.close()
if __name__ == '__main__':
    import socket
    # from multiprocessing import Process
    # 1.创建服务器socket对象
    server = socket.socket(family=socket.AF_INET,type=socket.SOCK_STREAM)
    # 2.绑定地址和端口(IP:port)
    server.bind(('0.0.0.0',9999)) # IP和PORT组成一个元组
    # 3.监听是否有客户端连接?listen
    server.listen(5) # 最大监听的客户端数量是5
    print('server start ......')
    while True:
        # 4.接收客户端连接accept
        clientsocketobj,clientaddress = server.accept()
        p = Thread(target=dealwithclient,args=(clientsocketobj,))
        p.start()
    # 7.关闭socket对象
    # clientsocketobj.close()
    # server.close()

多线程服务器:
在这里插入图片描述
协程-TCP服务器:
在这里插入图片描述
在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!
Python中的网络编程主要使用TCP/IP协议栈。TCP/IP协议栈是一个网络协议族,含了多种网络协议。其中最常用的是TCP和UDP协议。 Python提供了socket模块,可以使用它来实现网络编程。socket模块提供了各种功能来创建和使用套接字(socket)。套接字是用于网络通信的一种机制,类似于电话中的插头和插座。 下面是一个简单的TCP/IP客户端和服务器的例子: 服务器端: ```python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.bind(('localhost', 8888)) s.listen(5) while True: conn, addr = s.accept() print('Connected by', addr) while True: data = conn.recv(1024) if not data: break conn.sendall(data) conn.close() ``` 客户端: ```python import socket s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(('localhost', 8888)) s.sendall(b'Hello, world') data = s.recv(1024) s.close() print('Received', repr(data)) ``` 在服务器端,我们首先创建了一个套接字,并且绑定到了本地地址和端口。然后我们开始监听连接,当有客户端连接时,我们打印出客户端的地址并开始接收数据。如果客户端发送了空数据,则关闭连接。 在客户端,我们创建了一个套接字连接到服务器。然后我们发送了一条消息,并等待服务器的响应。最后,我们关闭了连接。 这只是一个简单的例子,实际中可能会有更多的代码来处理连接的错误和异常。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值