socket套接字

1、什么是socket

socket是一个模块,又称套接字,用来封装互联网协议(应用层以下的层)

2、为什么要有socket

实现应用层以下的层的工作,提高开发效率

3、怎么使用socket

先导入socket模块,先启动服务端套接字,再启动客户端套接字

# 服务端

import socket
# 买手机
server = socket.socket()
# 绑定手机号(IP,port)
# IP单机模式是127.0.0.1,局域网内使用cmd中ipconfig查询IPV4
# port设置8000以后的数据
server.bind(('127.0.0.1', 9876))
# 设置半连接池
server.listen(4)
# 可接收多个客户端数据连接,实现循环通信
while True:
# 接收客户端连接
conn, addr = server.accept()
# 查看对方地址
print(addr)
while True:
# 捕获异常机制
try:
# 接收客户端发来的数据,可一次接收1024bytes的数据
data = conn.recv(1024)
if len(date) == 0:
break
if data.decode('utf-8') == 'q':
break
print(data.decode('utf-8'))
# 向客户端发送消息
send_data = input('请输入向客户端发送的数据:')
conn.send(send_data.encode('utf-8'))
# 捕获异常,并打印出错误信息
except Exception as e:
print(e)
break
# 挂电话
conn.close()
# 客户端

import socket
# 买手机
client = socket.socket()
# 建立连接(IP,port)
client.connect(('127.0.0.1',9876))
while True:
try:
# 向对方发送数据
data = input('请输入向服务端发送的数据')
client.send((data.encode('utf--8')))
# 接收对方发来的数据可设置一次接收的bytes数,并打印
res_data = client.recv(1024)
if len(res_data) == 0:
break
if res_data.decode('utf-8') == 'q':
break
print(res_data.decode('utf-8'))
# 捕获异常,并打印出异常
except Exception as e:
print(e)
break
client.close()

粘包问题

问题1:

无法确认对方发送过来数据大小

问题2:

在发送数据间隔短并且数据量小的情况下,会将所有数据一次性发送

解决:需要确认对方发送的数据大小

# 客户端
# 问题1
import socket
client = socket.socket()
client.connect(('127.0.0.1', 9876))
while True:
try:
cmd = input('请输入向服务端发送的命令:')
client.send(cmd.encode('utf-8'))
# 接收服务端返回的数据
# 由于不知道会返回多少个bytes所以有问题1
date = client.recv(11910)
print(len(date))
print(date.decode('gbk'))
except Exception as e:
print(e)
break
client.close()
# 客户端
# 问题2
# 时间间隔短,并数据量小的情况下,会将所有的数据一次性发送,接收时不知道具体有几个
import socket
client = socket.socket()
client.connect(('127.0.0.1', 9876))
client.send(b'hello')
client.send(b'hello')
client.send(b'hello')
client.send(b'hello')
client.send(b'hello')
# 服务端

import socket
import subprocess server = socket.socket()
server.bind(('127.0.0.1', 9876))
server.listen(4)
while True:
conn, addr = server.accept()
print(addr) while True:
try:
# 接收客户端的数据,具体值不知道多大,所有有可能不能完全接收,有可能浪费资源
cmd = conn.recv(12)
if len(cmd) == 0:
break
cmd = cmd.decode('utf-8')
if cmd == 'q':
break
# 调用subprocess连接终端,对终端进行操作,并获取正确和错误的结果
obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
# 拿到结果,并打印
result = obj.stdout.read() + obj.stderr.read()
print(result.decode('gbk'))
# 将结果返回给客户端
conn.send(result) except Exception as e:
print(e)
break
conn.close()

解决粘包问题

使用struct模块

struct 是一个python内置的模块,它可以将固定长度的数据,打包成固定格式的长度

模式:i:4,或其他模式

作用:将真实数据做成一个固定长度的报头,发送给服务端,服务端接收报头,然后进行解包,获取真实数据的长度,进行接收数据即可

import struct
data = input('请输入传的数据').strip()
data = data.encode('utf-8')
# 制作报头,需要 i 的字符串和传入数据的长度
header = struct.pack('i',len(data))
print(header)
print(len(header)) # 解包( i 的字符串和报头)获取真实长度,得到一个元组,拿到元组第一个数就是真实长度
res = struct.unpack('i', header)[0]
print(res) # utf-8中一个中文是3个bytes,一个英文是1个bytes

客户端:

​ 1.先制作报头,并发送

​ 2.发送真实数据

服务端:

​ 1.接收报头,并且解包获取真实数据长度

​ 2.根据真实数据长度,接收真实数据

# 客户端
import socket
import struct client = socket.socket()
client.connect(('127.0.0.1', 9876))
while True:
try:
cmd = input('请输入向服务端发送的命令')
cmd_bytes = cmd.encode('utf-8')
# 做一个报头
header = struct.pack('i', len(cmd_bytes))
# 发送报头
client.send(header)
# 发送真实数据
client.send(cmd_bytes)
# 接受服务端返回的报头
reheader = client.recv(4)
# 解包
data_len = struct.unpack('i', reheader)[0]
result = client.recv(data_len)
print(result.decode('gbk'))
except Exception as e:
print(e)
break
client.close()
# 服务端
import socket
import subprocess
import struct server = socket.socket()
server.bind(('127.0.0.1', 9876))
server.listen(5)
while True:
conn, addr = server.accept()
while True:
try:
# 获取报头
header = conn.recv(4)
# 获取真实数据长度
data_len = struct.unpack('i', header)[0]
# 准备接受真实数据
cmd = conn.recv(data_len)
cmd = cmd.decode('utf-8')
if cmd == 'q':
break
if len(cmd) == 0:
break
obj = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
result = obj.stdout.read() + obj.stderr.read()
print(len(result))
print(result.decode('gbk'))
# 将结果返回给客户端
header = struct.pack('i', len(result))
conn.send(header)
conn.send(result)
except Exception as e:
print(e)
break
conn.close()
# 客户端
import socket
import struct
import json
client = socket.socket()
client.connect(('127.0.0.1', 9876))
while True:
# 伪装电影数据
movie_name = input('请输入电影名称:')
movie_len = 10000101
send_dic = {
'movie_name': movie_name,
'movie_len': movie_len
}
# 序列化
json_data = json.dumps(send_dic)
# 制作报头
json_bytes = json_data.encode('utf-8')
header = struct.pack('i', len(json_bytes))
# 发送报头
client.send(header)
# 发送真实数据
client.send(json_bytes)
# 服务端
import socket
import json
import struct server = socket.socket()
server.bind(('127.0.0.1', 9876))
server.listen(5)
while True:
conn, addr = server.accept()
print(addr)
while True:
try:
# 接收报头
header = conn.recv(4)
# 解包获取真实长度
json_len = struct.unpack('i', header)[0]
# 接收真实长度
json_bytes_data = conn.recv(json_len)
json_data = json_bytes_data.decode('utf-8')
# 反序列化得到数据
back_dic = json.loads(json_data)
print(back_dic)
except Exception as e:
print(e)
break
conn.close()

socket套接字及粘包问题的更多相关文章

  1. 网络编程——TCP协议、UDP协议、socket套接字、粘包问题以及解决方法

    网络编程--TCP协议.UDP协议.socket套接字.粘包问题以及解决方法 TCP协议(流式协议) ​ 当应用程序想通过TCP协议实现远程通信时,彼此之间必须先建立双向通信通道,基于该双向通道实现数 ...

  2. 网络编程 TCP协议:三次握手,四次回收,反馈机制 socket套接字通信 粘包问题与解决方法

    TCP协议:传输协议,基于端口工作 三次握手,四次挥手 TCP协议建立双向通道. 三次握手, 建连接: 1:客户端向服务端发送建立连接的请求 2:服务端返回收到请求的信息给客户端,并且发送往客户端建立 ...

  3. 02网络编程( socket套接字+TCP粘包 )

    目录 02 网络编程 一.socket套接字编程 二.简易代码模板 2.1 服务端 2.2 客户端 三.通信循环及代码优化 四.黏包现象 五.struct模块 六.简易版本报头 七.上传文件数据 * ...

  4. python开发socket套接字:粘包问题&udp套接字&socketserver

    一,发生粘包 服务器端 from socket import * phone=socket(AF_INET,SOCK_STREAM) #套接字 phone.setsockopt(SOL_SOCKET, ...

  5. TCP Socket 套接字 和 粘包问题

    一.Scoket 套接字 Scoket是应用层(应用程序)与TCP/IP协议通信的中间软件抽象层,它是一组接口.也可以理解为总共就三层:应用层,scoket抽象层,复杂的TCP/IP协议 基于TCP协 ...

  6. python基础--socket套接字、粘包问题

    本地回环地址:127.0.0.1 简易版服务端: import socket ​ server = socket.socket() # 就比如买了一个手机 server.bind(("127 ...

  7. day34 基于TCP和UDP的套接字方法 粘包问题 丢包问题

    TCP 基于流的协议 又叫可靠性传输协议 通过三次握手 四次挥手 来保证数据传输完毕 缺点效率低 正因为是基于流的协议 所以会出现粘包问题粘包问题:原因一:是应为数据是先发送给操作系统,在操作系统中有 ...

  8. Day09: socket网络编程-OSI七层协议,tcp/udp套接字,tcp粘包问题,socketserver

    今日内容:socket网络编程    1.OSI七层协议    2.基于tcp协议的套接字通信    3.模拟ssh远程执行命令    4.tcp的粘包问题及解决方案    5.基于udp协议的套接字 ...

  9. 基于UDP的套接字、粘包问题

    一.基于UDP的套接字 UDP服务端 ss = socket() #创建一个服务器的套接字 ss.bind() #绑定服务器套接字 inf_loop: #服务器无限循环 cs = ss.recvfro ...

随机推荐

  1. Nginx目录穿越漏洞

    Nginx (engine x) 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx经常被做为反向代理,动态的部分被proxy_pass传递给后端端口,而静 ...

  2. springcloud(五,多个服务注册中心eureka)

    spring cloud (一.服务注册demo_eureka) spring cloud (二.服务注册安全demo_eureka) spring cloud (三.服务提供者demo_provid ...

  3. springmvc单例

    默认情况下springmvc都是单例的,用@Controller注解的web页面,下次请求时,可以拿到controller成员变量的上次运行的信息. 比如:controller类里面有: Linked ...

  4. asp.net core 2.1 容器中使用 System.Drawing.Common 的问题

  5. PCA:主成分分析

    PCA的概念: 主要思想是将n维特征映射到k维上,这k维是全新的正交特征,这k维特征被称为主成分,在原数据的基础上重新构造出来k维.就是从原始的空间顺序的找出一组相互正交的坐标轴,新坐标轴的选择和数据 ...

  6. 互联网基础知识------OSI七层网络模型梗概

    OSI七层模型 七层网络结构: 应用层.表示层.会话层.传输层.网络层.数据链路层.物理层 一般也作五层 应用层.传输层.网络层.数据链路层.物理层(实体层) 引申问题:TCP/IP协议与http协议 ...

  7. secure-file-priv特性

    转载自:https://segmentfault.com/a/1190000009333563 当出现:1290 - The MySQL server is running with the --se ...

  8. 【LeetCode】145. Binary Tree Postorder Traversal

    Difficulty: Hard  More:[目录]LeetCode Java实现 Description https://leetcode.com/problems/binary-tree-pos ...

  9. linux 下 的串口模拟器 minicom 退出方法

    ctrl + a (或 A) 进入 minicom 的配置模式:终端外观上无任何变化! 然后按下 z (或 Z) 方可打开配置帮助界面 然后按下 x (或 X)退出

  10. 【JVM】jmap命令详解----查看JVM内存使用详情

    linux获取java进程PID: https://www.cnblogs.com/sxdcgaq8080/p/10734752.html 如果命令使用过程中报错,可能解决你问题的方案: https: ...