Socket 和 基于socket实现客户端于服务端通信

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_39062385/article/details/89714718

1.socket是什么?
socket就是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口。

socket理解套接字分为两类:
基于文件类型的套接字家族:AF_UNIX
基于网络类型的套接字家族:AF_INET

127.0.0.1:本地回环地址,只能访问本机。
套接字工作流程:

在这里插入图片描述

socket()模块函数用法
import socket
scoket.scoket(socket_family, socket_type, protocal = 0)
# socket_family 可以是:AF_UNIX或AF_INET;socket_type 可以是SOCK_STREAM或SOCK_DGRAM;protoca一般不填,默认值为0.
#获取tcp/ip套接字
tcpSock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# 获取udp/ip套接字
udpSock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)

服务端套接字函数
s.bind ()        绑定(主机,端口号)到套接字
s.listen()        开始TCP监听
s.accept()      被动接收TCP客户的连接,(阻塞式)等待连接的到来

客户端套接字函数
s.connect()      主动初始化TCP服务器连接
s.connect_ex()  connect()函数的扩展版本,出错返回错码,不会抛异常

公共用途的套接字函数
s.recv()            接收TCP数据
s.send()           发送TCP数据(send待发送数据量大于己端缓存区域剩余空间,数据丢失,不会发完)
s.sendall()        发送完整的TCP数据,(本质就是循环调用send,sendall在待发送数据量大于己端缓存区域剩余空间时,数据不会丢失,循环调用send直到发完)
s.recvfrom()      接收UDP数据
s.sendto()          发送UDP数据
s.getpeername()   连接到当前套接字的远端地址
s.getsockname()   当前套接字地址
s.getsockopt()     返回指定套接字的参数
s.setsockopt()     设置指定套接字参数
s.clsoe()               关闭套接字


基于TCP的套接字
tcp是基于链接的,必须先启动服务端,然后再启动客户端去链接服务端

最简单利用socket的 C/S实现

# client
import socket
client = socket.socket()
client.connect(('127.0.0.1',8080))
client.send(r'ARE YOU OKAY?')
date = client.recv(1024)
print(data)
client.close()

# server
import socket
server = socket.socket()
server.bind(('127.0.0.1', 8080))
server.listen(5)
conn ,addr = server.accept()
data = conn.recv(1024)
print(data)
conn.send(r'I am not okay')
conn.close() 
server.close()

链接循环

# client
import scoket
import struct
import json

client = socket.socket()
client.connect(('127.0.0.1',8081))
while True:
	msg = input('>>:').encode('utf-8')
	if len(msg) == 0 :continue # 输入为空,直接跳过
	client.send(msg)
	header = client.revc(4) 
	header_len = struct.unpack('i', header)[0] # 对这个头进行解包,获取真实数据的长度 ,struck主要是用来处理C结构数据的
	head_dic = json.loads(client.recv(head_len).decode('utf-8'))
	print(head_dic)
	total_size  = head_dic['len']
	recv_size =  0
	res = b''
	while recv_size < total_size:
		data = client.recv(1024)
		res +=data
		recv_size += len(data)
	print(res.decode('gbk'))

# server
import socket
import static
import json
import subprocess  #即允许你去创建一个新的进程让其执行另外的程序,并与它进行通信,获取标准的输入、标准输出、标准错误以及返回码等

"""
服务端:
要有固定的ip和port
24小时不间断提供服务
"""
server = socket.socket()
server.bind(('127.0.0.1', 8081))
server.listen(5)  # 半连接池
while True:
	conn,addr = server.accpet() # 阻塞
	while True:
		try:
			if len(data) == 0: break      # 针对linux和mac系统 客户端异常断开反复收空的情况
			obj = subprocess.Popen(data, shell = true, stdout = subprocess.PIPE,stderr = subprocess.PIPE)
			stdout  = obj.stdout.read()
			stderr = obj.stderr.read()
			print(len(stdout + stderr))
			header_dic = {
				'filename' : 'cls.av'
				'len':len(stdout + stderr)
			}
			 header_bytes = json.dumps(header_dic).encode('utf-8')  # 制作报头
			header = struct.pack('i', len(header_bytes)) # 将需要发送给客户端的数据打包成固定4个字节
			conn.send(header)
			conn.send(header_bytes)
			conn.send(stdout + stderr)
		except ConnectionResetError:
			break
	conn.close()
server.clsoe()
	


展开阅读全文

没有更多推荐了,返回首页