python之网络编程
为了实现在不同的电脑之间的通信,就需要使用网络编程。
TCP/IP简介:
互联网协议包含了上百种协议标准,其中最重要的两个协议就是TCP和IP协议
1、IP协议:
IP协议负责把数据从一台计算机通过网络发送到另一台计算机,由于互联网链路复杂,两台计算机之间经常有多条线路,因此,路由器就负责决定如何把一个IP包转发出去,IP包的特点是按块发送,途径多个路由,但是不保证都能到达,也不能保证顺利到达
2、TCP协议:
TCP协议是建立在IP协议之上的,TCP协议负责在两台计算机之间建立连接,保证数据包按顺序到达,通过3次握手建立可靠性连接,然后需要对每个IP包进行编号,确保对方按顺序收到,如果包丢掉了就自动重发。
UDP简介:
相对于TCP协议,UDP协议则是面向无连接的协议,使用UDP协议时,不需要建立连接,只需要知道对方的IP和端口号,就可以发送数据包,但是数据无法保证一定到达,虽然使用UDP传输数据不可靠,但它的优点是传输速度快,如果不要求可靠性到达的数据而言,可以考虑使用UDP协议
Socket简介:
为了让两个程序之间通过网路进行通信,二者均必须使用Socket套接字,通常也称为套接字,用于描述IP地址和端口,它是一个通信链的句柄,用于实现不同虚拟机或不同计算机之间的通信。
在Python中,使用socket模块的socket()函数就可以完成,语法格式如下:
s = socket.socket(AddressFamily,Type)
- Address Family:可以选择AF_INET(用于Internet进程间通信),或者AF_UNIX(用于同一台计算机进程间通信),实际工作中常用AF_INET
- Type:套接字类型,可以是SOCK_STREAM(流式套接字,主要用于TCP协议)或者SOCK_DGRAM(数据包套接字,主要用于UDP协议)
例如:通过下面方式创建TCP或者UDP套接字,如图:

注意:上面的socket.socket()中不加任何参数,默认情况下就是创建TCP套接字
创建完成后,生成一个socket对象,socket对象主要方法如下:
| 函数 | 描述 |
| s.bind() | 绑定地址(host,port)到套接字,在AF_INET下,以元组(host,port)形式表示地址 |
| s.listen() | 开启TCP监听,参数为在拒绝连接之前,操作系统可以挂起的最大连接数量,一般设置为5 |
| s.accept() | 被动接受TCP客户端连接(阻塞式),等待连接到来 |
| s.connect() | 主动初始化TCP连接,参数的格式一般为元组(hostname,port),如果连接出错,返回socket.error错误 |
| s.recv() | 接受TCP数据,数据以字符串形式返回,参数可以指定最大数据量 |
| s.send() | 发送TCP数据,将string中的数据发送到连接的套接字,返回值是要发送的字节数量 |
| s.sendall() | 完整发送TCP数据,将string中的数据发送到连接的套接字,在返回之前会尝试发送所有数据,成功返回None,失败抛出异常 |
| s.recvfrom() | 接受UDP数据,与recv()类似,返回值是(data,address),其中data是包含接受数据的字符串,address是发送数据的套接字地址 |
| s.sendto() | 发送UDP数据,将数据发送到套接字,address形式为(ipaddr,port)的元组,指定远程地址,返回值是发送的字节数 |
| s.close() | 关闭套接字 |
TCP编程
1、创建TCP服务器:
如果要完成一个TCP服务器的功能,需要的流程如下:
- 使用socket()创建一个套接字
- 使用bind()绑定IP和port
- 使用listen()使套接字变为可被动连接
- 使用accept()等待客户端连接
- 使用recv/send()接受和发送数据
例如:使用socket模块,通过客户端浏览器向本地服务器(127.0.0.1)发起请求,服务器接收到请求,向浏览器发送helloworld,创建一个server.py文件,如图 :

此时通过浏览器访问,结果如下:

2、创建TCP客户端:
上面的例子中是用浏览器作为客户端来接收数据,下面,创建一个TCP客户端,通过该客户端向服务器发送和接受消息,创建一个client.py,如图:

接下来同时启动第一步的服务端server.py和上图中的客户端client.py,然后在客户端中输入数据,服务器可以返回数据,如图:

3、执行TCP服务器和客户端
下面的例子实现了客户端和服务端的简易聊天,当有一方输入byebye后就退出,如图:
#服务端的代码
import socket
host = socket.gethostname() #获取主机地址
port = 12345
s = socket.socket() #创建TCP套接字
s.bind((host,port)) #绑定主机地址和端口
s.listen(1) #设置最多连接数量
sock,addr = s.accept() #被动接受TCP客户端连接
info = sock.recv(1024).decode() #decode()将byte类型转换为字符串
while info != 'byebye':
if info:
print("接受到的内容为:",info)
send_data = input("输入发送内容:")
sock.send(send_data.encode()) #发送TCPshuju
if send_data == 'byebye': #如果发送byebye就推出
break
info = sock.recv(1024).decode() #接受客户端数据
sock.close() #关闭客户端套接字
s.close() #关闭服务器套接字
#客户端代码
import socket
s = socket.socket() #创建TCP套接字
host = socket.gethostname()
port = 12345
s.connect((host,port))
info = ''
while info != 'byebye':
send_data = input("请输入发送内容:")
s.send(send_data.encode())
if send_data == 'byebye':
break
info = s.recv(1024).decode()
print("接受到的内容是:",info)
s.close()


