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  阅读(61)  评论(0)    收藏  举报