python-socket编程

image

TCP协议

一、简易版本

1、服务端

import socket
from socket import SOL_SOCKET, SO_REUSEADDR

new_socket = socket.socket()
new_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
new_socket.bind(('127.0.0.1', 8082))
new_socket.listen(5) --》mac本和linux本可以不写,本质是设置等待的客户的数量

conn, addr = new_socket.accept()
data=conn.rcve(1024)
conn.send(data.upper())
conn.close()

2、客户端

import socket

new_socket = socket.socket()
new_socket.connect(('127.0.0.1', 8082))

new_socket.send(b'judyjudy')
data=new_socket.rcve(1024)
print(data.decode('utf8'))
conn.close()

二、解决通道循环和通信循环以及优化

1、服务端

import socket
from socket import SOL_SOCKET, SO_REUSEADDR

new_socket = socket.socket()
new_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
#解决mac本端口占用问题
new_socket.bind(('127.0.0.1', 8082))
new_socket.listen(5) --》mac本和linux本可以不写
while True:
conn, addr = new_socket.accept()
while True:
data=conn.rcve(1024)
conn.send(data.upper())

2、客户端

import socket

new_socket = socket.socket()
new_socket.connect(('127.0.0.1', 8082))

while True:
data=input('please say something--->:').strip()
if len(data)==0: #客户端发送数据不能为空
continue
new_socket.send(data)
data_=new_socket.rcve(1024)
print(data_.decode('utf8'))

三、解决粘包问题

1、服务端

import socket
import subprocess
import struct
import json
from socket import SOL_SOCKET, SO_REUSEADDR

new_socket = socket.socket()
new_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
new_socket.bind(('127.0.0.1', 8082))
new_socket.listen()

while True:
conn, addr = new_socket.accept()
while True:
cmd = conn.recv(1024)
cmd = cmd.decode('utf8')
res = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
res1 = res.stdout.read() + res.stdout.read()
d = {'filename': 'judyjudy', 'file_size': len(res1), 'btw': 'enjoy!!!!'}
d_json = json.dumps(d)
d_size = struct.pack('i', len(d_json))
conn.send(d_size)
conn.send(d_json.encode('utf8'))
conn.send(res1)

2、客户端

import socket
import struct
import json

new_socket = socket.socket()
new_socket.connect(('127.0.0.1', 8082))

while True:
cmd = input('请输入您的指令>>>>>:')
if len(cmd) == 0:
continue
new_socket.send(cmd.encode('utf8'))
data = new_socket.recv(4)
dic_length = struct.unpack('i', data)[0]
dic_json = new_socket.recv(dic_length)
dic_real = json.loads(dic_json)
print(dic_real)
file_real_length = dic_real['file_size']
data_real=new_socket.recv(file_real_length)
print(data_real.decode('gbk'))

四、上传或者下载数据

1、服务端

import socket
import os
import struct
import json
from socket import SOL_SOCKET, SO_REUSEADDR

new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
new_socket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
new_socket.bind(('127.0.0.1', 8086))
new_socket.listen(5)
while True:
conn, addr = new_socket.accept()
recv_choice = conn.recv(1024)
if recv_choice.decode('utf8') == '2':
data = conn.recv(4)
dic_length = struct.unpack('i', data)[0]
dic_json = conn.recv(dic_length)
dic_real = json.loads(dic_json)
file_real_length = dic_real['file_size']
file_real_name = dic_real['filename']
recv_once_length = 0
while recv_once_length < file_real_length:
date_once = conn.recv(1024)
with open(file_real_name, 'wb') as f:
f.write(date_once)
recv_once_length += len(date_once)
else:
conn.send(b'completed')
elif recv_choice.decode('utf8') == '1':
data_base = '/Users/wendywwwww/Desktop/video'
movi- e_name = os.listdir(data_base)
movie_name_dic = {'file_list': movie_name}
movie_name_dic_json = json.dumps(movie_name_dic)
fake_length = struct.pack('i', len(movie_name_dic_json))
conn.send(fake_length)
conn.send(movie_name_dic_json.encode('utf8'))
client_choice = conn.recv(1024)
client_choice = client_choice.decode('utf8')
client_choice = int(client_choice)
file_real_name = movie_name[client_choice - 1]
file_path = os.path.join(data_base, file_real_name)
file_size = os.path.getsize(file_path)
d = {'filename': 'judy的下载', 'file_size': file_size, 'btw': 'enjoy!!!!'}
d_json = json.dumps(d)
d_size = struct.pack('i', len(d_json))
print('1')
conn.send(d_size)
conn.send(d_json.encode('utf8'))
with open(file_path, 'rb') as f:
for line in f:
conn.send(line)

2、客户端

import socket
import struct
import json
import os

new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
new_socket.connect(('127.0.0.1', 8086))
data_base = '/Users/wendywwwww/Desktop/video'
while True:
choice = input('please choose -> 1 download or 2 upload >>>>>> : ').strip()
if choice == '2':
if choice.isdigit():
new_socket.send(choice.encode('utf8'))
movie_name = os.listdir(data_base)
for i, j in enumerate(movie_name, 1):
print(i, j)
client_choice = input('please choose the number >>>>: ').strip()
if client_choice.isdigit():
client_choice = int(client_choice)
if client_choice in range(1, len(movie_name) + 11):
file_name = movie_name[client_choice - 1]
file_path = os.path.join(data_base, file_name)
file_size = os.path.getsize(file_path)
d = {'filename': 'judy的小测试', 'file_size': file_size, 'btw': 'enjoy!!!!'}
d_json = json.dumps(d)
d_size = struct.pack('i', len(d_json))
new_socket.send(d_size)
new_socket.send(d_json.encode('utf8'))
with open(file_path, 'rb') as f:
for line in f:
new_socket.send(line)
reply=new_socket.recv(1024)
priint(reply.decode('utf8'))
elif choice == '1':
if choice.isdigit():
new_socket.send(choice.encode('utf8'))
data = new_socket.recv(4)
dic_length = struct.unpack('i', data)[0]
dic_json = new_socket.recv(dic_length)
dic_real = json.loads(dic_json)
movie_name_list = dic_real['file_list']
for i, j in enumerate(movie_name_list, 1):
print(i, j)
client_choice = input('please choose the number >>>>: ')
if client_choice.isdigit():
if int(client_choice) in range(1, len(movie_name_list) + 1):
new_socket.send(client_choice.encode('utf8'))
data = new_socket.recv(4)
dic_length = struct.unpack('i', data)[0]
dic_json = new_socket.recv(dic_length)
dic_real = json.loads(dic_json)
file_real_length = dic_real['file_size']
file_real_name = dic_real['filename']
recv_once_length = 0
while recv_once_length < file_real_length:
date_once = new_socket.recv(1024)
with open(file_real_name, 'wb') as f:
f.write(date_once)
recv_once_length += len(date_once)
else:
print('completed')

🌹 测试成功
image

⚠️ 注意事项
1、变量名后面跟冒号,表示的意思是该变量名需要指代的数据类型
2、函数名+'->'表示后面是函数的返回值

UDP协议

和tcp十分相像

1、服务端

import socket

new_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip_port = ('127.0.0.1',9090)

new_socket.bind(ip_port)

while True:
msg, address = new_socket.recvfrom(1024)
print(msg, address)
new_socket.sendto(msg.upper(), address)

2、客户端

import socket

new_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
ip_port = ('127.0.0.1', 9090)
while True:
data = input('>>>>>: ').strip()
new_socket.sendto(data.encode('utf8'), ip_port)
msg, address = new_socket.recvfrom(1024)
print(msg.decode('utf8'))

socketserver模块的使用

🌹🌹🌹 实现并发

1、服务端

import socketserver

class JUDyrequeat(socketserver.BaseRequestHandler):
def handle(self): # 一定要建立这个函数
while True: #这里干的就是通信循环
data = self.request.recv(1024) # self.request 相当于accept建立的通道
if len(data) == 0:
break
print(data.decode('utf8'))
self.request.send(data.upper())
self.request.close()

server = socketserver.ThreadingTCPServer(('127.0.0.1', 9090), JUDyrequeat, bind_and_activate=True) # ThradingTCPServer 造的是多线程,因为套接字io比较多
server.serve_forever() # server是产生的对象,调出serve_forever表示永远提供服务。干的就是链接循环的工作

2、客户端 # 客户端不变

import socket

new_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ip = '127.0.0.1'
port = 9090
new_socket.connect((ip, port))
while True:
data = input('>>>>>>: ').strip()
new_socket.send(data.encode('utf8'))
data = new_socket.recv(1024)
print(data.decode('utf8'))

posted @ 2022-01-12 16:42  JudyJU  阅读(87)  评论(0)    收藏  举报