Akemi

Python socket模块案例—简单网络编程

2024/11/13

网络编程的内容,不多介绍了,支持udp,tcp等协议

方法—socket.socket([family,[type,[proto]]])

创建套接子对象

参数:

family-地址簇,包含:socket.AF_INET ipv4地址簇;socket.AF_INET6 ipv6地址簇
type-套接字类型,包含:socket.SOCK_STREAM tcp协议;socket.SOCK_DGRAM udp协议
proto-协议号,通常为0,表示使用默认协议
返回值-套接字对象

方法—socket.bind(address,port)

将套接字与地址和端口绑定,用以传输数据(其实是和网卡绑定)

方法—socket.listen(number)

套接子监听状态,可以定义最大连接数

方法—socket.accept()

接受一个客户端请求,返回一个元组(套接字和客户端地址
(套接子对象,addr+port)
conn,addr = socket.accept()

方法——socket.send(b’xx’)

发送数据

方法——socket.recv(num)

接收到的数据,定义最大接收字节数

方法——socket.close()关闭套接子

方法——conn.close()关闭连接

案例:多线程聊天服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# 服务器端
#coding=utf-8
import socket
import threading
# 定义多线程函数
def handle_connection(conn,addr):
print(f'客户端{addr}已连接')
try:
while True:
msg=conn.recv(1024)
# 如果没有收到消息
if not msg:
print(f'客户端{addr}已断开')
break
print(f"收到客户端{addr}消息:{msg.decode()}")
except Exception as e:
print(e)
finally:
conn.close()
print(f"客户端{addr}已关闭")
# 创建tcp套接字
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
server.bind(('localhost',8081))
server.listen(5)
print('聊天服务器启动,等待客户端连接')
while True:
conn,addr=server.accept()
# 为每个客户端创建一个线程,target即新线程使用后面的函数处理
client_thread=threading.Thread(target=handle_connection,args=(conn,addr))
client_thread.start()
except Exception as e:
print(f'服务错误:{e}')
finally:
server.close()

# 客户端
#coding=utf-8
import socket
def start_client():
client_socket=socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try:
client_socket.connect(('localhost',8081))
while True:
msg=input("输入消息或exit退出:")
# 筛出exit,直接跳出,进入finally
if msg == "exit":
break
client_socket.send(msg.encode('utf-8'))
print(f"msg:{msg} is send")
response=client_socket.recv(1024)
print(f"服务器响应内容{response.decode('utf-8')}")
except Exception as e:
print(f"客户端出现错误:{e}")
finally:
client_socket.close()
if __name__ == "__main__":
start_client()

案例:多线程双工聊天服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# 服务器端
#coding=UTF-8
import socket
from threading import Thread
# 定义两个函数,分别管收发
def recv_data():
while True:
re_data = tcp_client_socket.recv(1024).decode("utf-8")
print(f"B:{re_data}")
if re_data == 'EOF':
break
def send_data():
while True:
msg = input("发送信息或输入EOF退出:")
tcp_client_socket.send(msg.encode("utf-8"))
if msg == "EOF":
break
if __name__ == '__main__':
tcp_server_socket = socket(AF_INET, SOCK_STREAM)
tcp_server_socket.bind(("127.0.0.1",9000)) # 绑定端口
tcp_server_socket.listen(5)
print("等待连接")
tcp_client_socket,host = tcp_server_socket.accept()
print("连接成功")
t1 = Thread(target=recv_data)
t2 = Thread(target=send_data)
t1.start()
t2.start()
t1.join() # 等待并行
t2.join()
tcp_client_socket.close()
tcp_server_socket.close()

# 客户端
#coding=UTF-8
import socket
from threading import Thread
# 定义两个函数,分别管收发
def recv_data():
while True:
recv_data = tcp_client_socket.recv(1024).decode("utf-8")
print(f"A:{recv_data}")
if recv_data == 'EOF':
break
def send_data():
while True:
msg = input("发送信息或输入EOF退出:")
tcp_client_socket.send(msg.encode("utf-8"))
if msg == 'EOF':
break
if __name__ == '__main__':
tcp_client_socket = socket(AF_INET, SOCK_STREAM)
tcp_client_socket.connect(("127.0.0.1",9000))
print("连接成功")
t1 = Thread(target=recv_data)
t2 = Thread(target=send_data)
t1.start()
t2.start()
t1.join()
t2.join()
tcp_client_socket.close()

案例:文件传输服务器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# 创建tcp服务器
#coding=utf-8
import socket
filename = 'deployment.yaml'
# 定义发送函数
def send_file(conn, filename):
with open(filename,'rb') as f:
# 海象运算符,将后面的值赋给前面,即逐块读取文件
while(chunk := f.read(1024)):
conn.send(chunk)
print('文件传输完成')

if __name__ == '__main__':
# 创建与绑定套接子
server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
server.bind(('localhost',8000))
server.listen(3)
print("文件服务器已启动,等待连接")
conn,addr=server.accept()
print(f"客户端{addr}已连接")
send_file(conn,filename)
print(f"文件{filename}已发送")
conn.close()
server.close()

# 文件传输客户端
#coding=utf-8
import socket
# 接受文件
def receive_file(conn,filename):
with open(filename,'wb') as f:
# 每次接受数据并写入,没有数据就结束
while True:
data=conn.recv(1024)
if not data:
break
f.write(data)
print("文件成功传输")

if __name__ == '__main__':
tcp_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
tcp_client.connect(('localhost',8000))
receive_file(conn=tcp_client,filename='receive_file')
tcp_client.close()
CATALOG
  1. 1. 案例:多线程聊天服务器
  2. 2. 案例:多线程双工聊天服务器
  3. 3. 案例:文件传输服务器