37、初识网络编程

网络编程 / 2021-01-08

学习此章节知识前,请确保自己拥有网络基础知识的储备!

一、socket

1.1、何为socket?

socket即套接字,应用程序通常使用“套接字”向网络另一端发起请求或响应请求,以此实现计算机之间或者同一台计算机的进程间通信!socket是一组接口,它把TCP/IP协议簇封装在socket接口后面,使得我们能够非常方便地进行编写网络相关的应用程序!

1.1.1、AF_UNIX

Unix和Linux都是一切皆文件,套接字均基于文件系统实现数据调度;它只能在同一台机器上不同进程之间使用!

1.1.2、AF_INET

基于网络类型的套接字,因此可跨主机通信,这也是我们学习的重点!

1.2、为何用socket?

为能进行跨主机间进程通信!

1.3、如何用socket?

先来模拟一下场景:sanxi跟chrystal进行语音通话,sanxi先拨号,chrystal听到响铃接起电话;通话连接建立成功,开始交流;交流结束,挂断电话结束对话!

Python提供了一个模块,就叫socket!下面展示一下socket基本语法:

import socket
socket.socket(socket_family,socket_type,protocal=0)
'''
socket_family有两种:AF_UNIX、AF_INET
socket_type:SOCK_STREAM(TCP协议)、SOCK_DGRAM(UDP协议)
protocal:不用填,默认即可!
'''
1.3.1、基于TCP的socket
服务端
import socket

ip_port = ('127.0.0.1', 8080)
buffer_size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # 创建套接字
server.bind(ip_port)  # bind()即绑定服务端IP地址与端口
server.listen(2)  # listen()即最大连接数,半连接池即俗称的并发数!
while True:
    connect, client_addr = server.accept()  # accept()即阻塞式等待连接
    print(f'接收到来自{client_addr} 的消息:')
    while True:
        # recv()即接收TCP数据,单次最大接收大小,单位为bytes;1024即1KB
        receive_data = connect.recv(buffer_size)
        print(receive_data.decode('utf-8'))
        if len(receive_data) == 0:  # 收不到消息后,中断循环,避免无数据传输也死磕在这!
            break
        connect.send('Hello'.encode('utf-8'))  # send()即发送数据
    connect.close()
客户端
import socket

ip_port = ('127.0.0.1', 8080)
buffer_size = 1024
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

client.connect_ex(ip_port)  # 连接远程服务端;connect_ex比connect多了个连接错误时返回异常状态码而不是报错
while True:
    msg = input('请输入交互内容,退出请键入quit:').strip()
    if len(msg) == 0:
        print('内容不能为空!')
        continue
    elif msg == 'quit':
        break
    client.send(msg.encode('utf-8'))
    data = client.recv(buffer_size)
    print(data.decode('utf-8'))
client.close()
测试结果

先启动服务端,接着启动客户端;启动完成后在客户端操作如下:

# 客户端操作
请输入交互内容,退出请键入quit:sanxi
Hello
请输入交互内容,退出请键入quit:quit

Process finished with exit code 0

# 服务端响应
接收到来自('127.0.0.1', 60791) 的消息:
sanxi
# 当客户端close连接后,服务端继续阻塞式等待连接!因为我们服务端的夙愿是永远服务!
1.3.2、基于UDP的socket

UDP因为不需要三次握手四次挥手的过程,因此代码也非常精简,速度也比TCP快很多,除了不靠谱!

服务端
import socket

ip_port = ('127.0.0.1', 8080)
buffer_size = 1024
server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)  # 创建UDP套接字
server.bind(ip_port)
while True:
    receive_data, client_addr = server.recvfrom(buffer_size)
    print(f'接收到来自{client_addr} 的消息:')
    print(receive_data.decode('utf-8'))
    server.sendto('Hello'.encode('utf-8'), client_addr)  # sendto()即发送UDP数据,第二个参数为元祖形式的ip+port
客户端
import socket

ip_port = ('127.0.0.1', 8080)
buffer_size = 1024
client = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

while True:
    msg = input('请输入交互内容,退出请键入quit:').strip()
    if not msg:
        continue
    elif msg == 'quit':
        break
    client.sendto(msg.encode('utf-8'), ip_port)
    server_data, server_addr = client.recvfrom(buffer_size)
    print(server_data.decode('utf-8'), server_addr)
测试结果:
# 客户端
请输入交互内容,退出请键入quit:chrystal
Hello ('127.0.0.1', 8080)
请输入交互内容,退出请键入quit:quit

# 服务端
接收到来自('127.0.0.1', 55139) 的消息:
chrystal

基于上述,可以做聊天软件、时间服务器等小程序!

世间微尘里 独爱茶酒中