目录
一.套接字(socket)的初使用
socket(简称 套接字) 是进程间通信的一种方式,它与其他进程间通信的一个主要不同是:
它能实现不同主机间的进程间通信,我们网络上各种各样的服务大多都是基于 Socket 来完成通信的例如我们每天浏览网页、QQ 聊天、收发 email 等等
格式:
import socket
socket.socket(family=AF_INET,type=SOCK_STREAM,proto=0,fileno=None)
参数 | 说明 |
family | 地址系列应为AF_INET(默认值),AF_INET6,AF_UNIX,AF_CAN或 AF_RDS。(AF_UNIX 域实际上是使用本地 socket 文件来通信) |
type | 套接字类型应为SOCK_STREAM(默值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。 SOCK_STREAM 是基于TCP的,有保障的(即能保证数据正确传送 到对方)面向连接的SOCKET,多用于资料传送。 SOCK_DGRAM 是基于UDP的,无保障的面向消息的socket,多用 于在网络上发广播信息。 |
proto | 协议号通常为零,可以省略,或者在地址族为AF_CAN的情况下,协议 应为CAN_RAW或CAN_BCM之一。 |
fileno | 如果指定了fileno,则其他参数将被忽略,导致带有指定文件描述符 的套接字返回。 与socket.fromfd()不同,fileno将返回相同的套接字,而不是重复 的。 这可能有助于使用socket.close()关闭一个独立的插座。 |
二.基于TCP协议的socket
- TCP协议,传输控制协议(英语:Transmission Control Protocol,缩写为 TCP)是一种面向连接的、可靠的、基于字节流的传输层通信协议,由IETF的RFC 793定义。
- TCP通信需要经过创建连接、数据传送、终止连接三个步骤。
- TCP通信模型中,在通信开始之前,一定要先建立相关的链接,才能发送数据,类似于生活中,"打电话""
面向连接
- 通信双方必须先建立连接才能进行数据的传输,双方都必须为该连接分配必要的系统内核资源,以管理连接的状态和连接上的传输。
- 双方间的数据传输都可以通过这一个连接进行。
- 完成数据交换后,双方必须断开此连接,以释放系统资源。
- 这种连接是一对一的,因此TCP不适用于广播的应用程序,基于广播的应用程序请使用UDP协议。
可靠
- TCP 采用发送应答机制
- TCP发送的每个报文段都必须得到接收方的应答才认为这个TCP报文段传输成功
- 2)超时重传
- 发送端发出一个报文段之后就启动定时器,如果在定时时间内没有收到应答就重新发送这个报文段。
- TCP为了保证不发生丢包,就给每个包一个序号,同时序号也保证了传送到接收端实体的包的按序接收。
- 然后接收端实体对已成功收到的包发回一个相应的确认(ACK);如果发送端实体在合理的往返时延(RTT)内未收到确认,那么对应的数据包就被假设为已丢失将会被进行重传。
- 3)错误校验
- TCP用一个校验和函数来检验数据是否有错误;在发送和接收时都要计算校验和。
- 4) 流量控制和阻塞管理
- 流量控制用来避免主机发送得过快而使接收方来不及完全收下。
三.TCP通信模型与UDP通信模型
3.1TCP通信模型
3.2UDP通信模型
四.TCP代码编写
服务器端:
import socket
sk = socket.socket()
sk.bind(('127.0.0.1',8080)) #把地址绑定到套接字
sk.listen() #监听链接
coon,addr = sk.accept() #接受客户端链接
print(coon,addr)
print(addr)
ret = coon.recv(1024)
print(ret)
coon.send(b'hi') #向客户端发送信息
coon.close() #关闭客户端套接字
sk.close() #关闭服务器套接字(可选)
客户端:
import socket
sk = socket.socket() # 创建客户套接字
sk.connect(('127.0.0.1',8080)) # 尝试连接服务器
sk.send(b'hello!')
ret = sk.recv(1024) # 对话(发送/接收)
print(ret)
sk.close() # 关闭客户套接字
Python 字符串前面加u,r,b的含义_如玉少年-_-的博客-CSDN博客_python字符串前加u
如果出现ip地址或端口被占用,如下解决办法:
#加入一条socket配置,重用ip和端口
import socket
from socket import SOL_SOCKET,SO_REUSEADDR
sk = socket.socket()
sk.setsockopt(SOL_SOCKET,SO_REUSEADDR,1)#就是它,在bind前加
sk.bind(('127.0.0.1',8898)) #把地址绑定到套接字
sk.listen() #监听链接
coon,addr = sk.accept() #接受客户端链接
ret = coon.recv(52) #接收客户端信息
print(ret) #打印客户端信息
i = input('你要发送的消息:')
print(type(i))
coon.send(i.encode('utf-8')) #向客户端发送信息
coon.close() #关闭客户端套接字
sk.close() #关闭服务器套接字
五. 基于UDP协议的socket
创建一个基于udp的网络程序流程很简单,具体步骤如下:
- 创建客户端套接字
- 发送/接收数据
- 关闭套接字
udp是无链接的,启动服务之后可以直接接受消息,不需要提前建立链接
服务器端:
import socket
udp_sk = socket.socket(type=socket.SOCK_DGRAM) #创建一个服务器的套接字
udp_sk.bind(('127.0.0.1',8808)) #绑定服务器套接字
msg,addr = udp_sk.recvfrom(1024)
print(msg)
print(addr)
udp_sk.sendto(b'hello',addr) # 对话(接收与发送)
udp_sk.close() # 关闭服务器套接字
client端:
import socket
ip_port = ('127.0.0.1',8808)
udp_sk = socket.socket(type=socket.SOCK_DGRAM)
udp_sk.sendto(b"hello",ip_port)
back_msg,addr = udp_sk.recvfrom(1024)
print(back_msg.decode('utf-8'),addr)
六.公共用途的套接字函数
- s.recv()
- 接收TCP数据,数据以字符串形式返回,bufsize指定要接收的最大数据量。flag提供有关消息的其他信息,通常可以忽略。
- s.send()
发送TCP数据,将string中的数据发送到连接的套接字。返回值是要发送的字节数量,该数量可能小于string的字节大小。 - s.sendall()
完整发送TCP数据,完整发送TCP数据。将string中的数据发送到连接的套接字,但在返回之前会尝试发送所有数据。成功返回None,失败则抛出异常。 - s.recvfrom()
接收UDP数据,与recv()类似,但返回值是(data,address)。其中data是包含接收数据的字符串,address是发送数据的套接字地址。 - s.sendto()
发送UDP数据,将数据发送到套接字,address是形式为(ipaddr,port)的元组,指定远程地址。返回值是发送的字节数。 - s.close()
关闭套接字
七.python_控制台输出带颜色的文字方法
在python开发的过程中,经常会遇到需要打印各种信息。海量的信息堆砌在控制台中,就会导致信息都混在一起,降低了重要信息的可读性。这时候,如果能给重要的信息加上字体颜色,那么就会更加方便用户阅读了。
当然了,控制台的展示效果有限,并不能像前段一样炫酷,只能做一些简单的设置。不过站在可
读性的角度来看,已经好很多了。
书写格式,和相关说明如下:
#格式: 设置颜色开始 :\033[显示方式;前景色;背景色m
#说明:
前景色 背景色 颜色
30 40 黑色
31 41 红色
32 42 绿色
33 43 黃色
34 44 蓝色
35 45 紫红色
36 46 青蓝色
37 47 白色
显示方式 意义
0 终端默认设置
1 高亮显示
4 使用下划线
5 闪烁
7 反白显示
8 不可见
#例子:
\033[1;31;40m <!--1-高亮显示 31-前景色红色 40-背景色黑色-->
\033[0m <!--采用终端默认设置,即取消颜色设置-->
例子:
print('\033[4;31;40m欢迎使用学生管理网站\033[0m')
try:
num = int(input('请输入数字选择功能:'))
print(f'\033[4;{num};43m欢迎使用学生管理网站\033[0m')
except Exception as e:
print(f'\033[1;31;40m对不起!你输入的内容有误~\033[0m')