socket基本语法和粘包
一。基本语法
127.0.0.1 是本地回环地址
客户端 服务端
import socket import socket
client=socket.socket() server=socket.socket() #买手机
ip_port=('127.0.0.1',8088) ip_port=('127.0.0.1',8088)
client.connect(ip_port) #连接的是一个元组,所以提前写好需要输入的IP和port server.bind(ip_port) #插电话卡 注意括号内是一个小元组,避免出错,先将Ip_port先写在外面
server.listen(5) #监听状态 5是半连接池
conn,addr=server.accept() #建立通信,已完成三次握手
client.secd(b'hello boy!') data=conn.recv (1024) # 和客户端对照者写,move right 必须是一个输入,一个接受,否则就会出现双方都在输入/输出状态,就会出现阻塞现象
print(data)
data=client.recv(1024) conn.send(b'hihihihihi')
print(data) conn.close()
client.close() #一次通信结束 server.close()
二。通信循环
上面我们已经可以实现两个计算机之间的相互通信,但是只是一次通信,如果要多次通信,就得多次输入,我们前面学过的可以多次输入的有什么?while循环
客户端 服务端
import socket import socket
client=socket.socket() server=socket.socket() #买手机
ip_port=('127.0.0.1',8088) ip_port=('127.0.0.1',8088)
client.connect(ip_port) #连接的是一个元组,所以提前写好需要输入的IP和port server.bind(ip_port) #插电话卡 注意括号内是一个小元组,避免出错,先将Ip_port先写在外面
server.listen(5) #监听状态 5是半连接池
conn,addr=server.accept() #建立通信,已完成三次握手
while True: while True:
client.send(b'hello boy!') data=conn.recv (1024)
print(data)
data=client.recv(1024) conn.send(b'hihihihihi')
print(data)
conn.close()
client.close() #一次通信结束 server.close()
三。链接循环
通信循环也已经实现了两台计算机之间的多次信息交流,但是发现只能一次服务一个客户端,但是服务端的特点是24小时不间断的提供服务,并且是提供给多个用户,地址也是不变的,那么如何实现提供多个服务给用户呢?链接循环走起来!
客户端 服务端
import socket import socket
client=socket.socket() server=socket.socket() #买手机
ip_port=('127.0.0.1',8088) ip_port=('127.0.0.1',8088)
client.connect(ip_port) #连接的是一个元组,所以提前写好需要输入的IP和port server.bind(ip_port) #插电话卡 注意括号内是一个小元组,避免出错,先将Ip_port先写在外面
server.listen(5) #监听状态 5是半连接池
while True: #这里就可以实现多个客户服务,所以得将建立连接信息放到第一个while里面 我们发现最多只可以打开6个客户端,一旦超过就报错
这是因为半连接池是5,就相当于只提供了5个凳子,先服务第一个用户,外面可以由5个人在 等,但是再来一个就报错!
conn,addr=server.accept() #建立通信,已完成三次握手
while True: while True:
client.send(b'hello boy!') data=conn.recv (1024)
print(data)
data=client.recv(1024) conn.send(b'hihihihihi')
print(data)
conn.close()
client.close() #一次通信结束 server.close()
四。异常处理
实际生活中:
1,用户提前中断了通道,会发现服务端直接报错,所以要对这个进行异常捕获
2.网络信号不好导致的问题
3.tcp协议是流的传输,输入信息不可以是空
客户端 服务端
import socket import socket
client=socket.socket() server=socket.socket() #买手机
ip_port=('127.0.0.1',8088) ip_port=('127.0.0.1',8088)
client.connect(ip_port) #连接的是一个元组,所以提前写好需要输入的IP和port server.bind(ip_port) #插电话卡 注意括号内是一个小元组,避免出错,先将Ip_port先写在外面
server.listen(5) #监听状态 5是半连接池
while True:
conn,addr=server.accept() #建立通信,已完成三次握手
while True:
msg=input('>>>:').encode('utf-8')
if len(msg)==0:continue while True:
try:
client.send(msg) data=conn.recv (1024)
if len(data)==0:break #针对mac 和Linux系统,需要自己再加一步
print(data)
data=client.recv(1024) conn.send(b'hihihihihi')
print(data) except ConnectionRaseError:break
conn.close()
client.close() #一次通信结束 server.close()
五。粘包问题
发现当自己输入的是task list之类的东西时,然后再次输入dir但是还是接收的是task list的信息,就是粘包,两个数据粘在了一起,解决方式
1.将recv的值改大,但是不是根本性的解决方式,因为你不知道用户传入的东西是多大,所以不推荐
2.将我们要传的东西先打包成固定大小,对方接受以后解包,看到大小,然后再根据大小来接受我们要传的东西(看下面总结)
总结:
发送消息端:
1.先发报头 2.在发字典(序列化成字符串) 3.再发你的真实数据
接收消息端:
1.先收4个长度的报头 2.解包拿到字典数据长度 3.接收字典(反序列化)获取字典里面的所有信息 4.接收真实数据
用到的模块分别是struck(pack,unpack),subprocess(标准输出stdout和错误流stderr) json(序列化dumps和反序列化loads) 以及socket
客户端
import socket
import json
import struct
client=socket.socket()
ip_port=('127.0.0.1',8099)
client.connect(ip_port) while True:
msg=input('>>>:').strip().encode('utf-8')
if len(msg)==0:continue
client.send(msg)
head=client.recv(4) #head就是4
#对这个报头进行解包,获取真实数据的长度
head_len=struct.unpack('i',head)[0]
head_dic=json.loads(client.recv(head_len).decode('utf-8')) #反序列化
print(head_dic) total_size=head_dic['len'] #一定要由索引0
# unpack拿出来的是一个小元组
print(total_size) #如果发送内容过大,怎么做,循环接收值 recv_size=0
res=b''
while recv_size<total_size: #对需要的数据进行循环接受
data=client.recv(1024)
res+=data
recv_size+=len(data) #len(data)真实收到的数据,所以是data,不是1024
print(res.decode('gbk')) 服务端:
#服务端给用户端发送一个字典的内容
import socket
import struct
import json
import subprocess server=socket.socket() ip_port=('127.0.0.1',8099) server.bind(ip_port) server.listen(5) while True: conn,addr=server.accept() while True:
try:
data=conn.recv(1024)
if len(data)==0:break
print(data)
order=subprocess.Popen(data.decode('utf-8'),
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
) stdout=order.stdout.read()
stderr=order.stderr.read()
#传过来的真实长度
print(len(stderr+stdout))
#传字典
head_dic = {
'file_name': 'cls.txt',
'len': len(stdout + stderr)
}
#字典序列化
head_bytes=json.dumps(head_dic).encode('utf-8') #制作报头
head=struct.pack('i',len(head_bytes)) #将需要发送给客户端的打包成4个字节 conn.send(head) #head=4想拿到一些描述,传个字典 conn.send(head_bytes)
conn.send(stderr+stdout)
except ConnectionResetError:break
socket基本语法和粘包的更多相关文章
- day8---多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- c# Socket通讯中关于粘包,半包的处理,加分割符
using System; using System.Collections.Generic; using System.Text; using System.Net.Sockets; using S ...
- python socket网络编程之粘包问题详解
一,粘包问题详情 1,只有TCP有粘包现象,UDP永远不会粘包 你的程序实际上无权直接操作网卡的,你操作网卡都是通过操作系统给用户程序暴露出来的接口,那每次你的程序要给远程发数据时,其实是先把数据从用 ...
- Python开发【socket篇】解决粘包
客户端 import os import json import struct import socket sk = socket.socket() sk.connect(('127.0.0.1',8 ...
- 11.1、socket连接中的粘包、精确传输问题
粘包: 发生原因: 当调用send的时候,数据并不是即时发给客户端的.而是放到了系统的socket发送缓冲区里,等缓冲区满了.或者数据等待超时了,数据才会发送,所以有时候发送太快的话,前一份数据还没有 ...
- 6.2 socket 流协议与粘包
TCP IP协议是流协议,对上层协议来讲是没有边界的,主机A发送两个消息M1和M2,如下图所示: 主机A发送了M1和M2,主机B在接收时有4种情况: 1.先收了M1,又收了M2 2.M1.M2一起收到 ...
- day08 多线程socket 编程,tcp粘包处理
复习下socket 编程的步骤: 服务端: 1 声明socket 实例 server = socket.socket() #括号里不写 默认地址簇使用AF_INET 即 IPv4 ...
- socket基于TCP(粘包现象和处理)
目录 6socket套接字 7基于TCP协议的socket简单的网络通信 AF_UNIX AF_INET(应用最广泛的一个) 报错类型 单一 链接+循环通信 远程命令 9.tcp 实例:远程执行命令 ...
- python笔记8 socket(TCP) subprocess模块 粘包现象 struct模块 基于UDP的套接字协议
socket 基于tcp协议socket 服务端 import socket phone = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 买 ...
随机推荐
- scss入门学习(一)
sass的文件后缀名 sass是目前流行的css预处理语言.sass有两种后缀文件,一种是.sass,不允许使用大括号和分号:另一种是.SCSS,允许使用大括号和分号,类似于我们平时写css的语法习惯 ...
- Javascript中的局部变量、全局变量的详解与var、let的使用区别
前言 Javascript中的变量定义方式有以下三种方式:1.直接定义变量,var与let均不写: a = 10; 2.使用var关键字定义变量 var a = 10; 3.使用let关键字定义变量 ...
- C++走向远洋——40(第九周,深复制体验)
*/ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...
- 【视频+图文】带你快速掌握Java中含break语句的双重for循环
双重for循环掌握后,我们就一起来看看双重for循环的进阶内容一之带break语句的双重for循环. 双重for循环[视频+图文]讲解传输门:点击这里可去小乔的哔哩哔哩观看~ 带continue语句的 ...
- win10下LoadRunner12 下载安装图文教程
1.下载安装包: 链接:https://pan.baidu.com/s/1hiGC9FjfKOFRWHVfMAHaeg 提取码:sr8x 如下图所示,咱们直接安装社区版“HP_LoadRunner_1 ...
- JavaScript sort() 对json进行排序(数组)
function up(x,y){//升序 return x[val.prop] - y[val.prop] } function down(x,y){//降序 return y[val.prop] ...
- vue 动态加载图片路径报错解决方法
最近遇到图片路径加载报错的问题 之前一直都是把图片放到assets的文件下的.总是报错,看到一些文章并且尝试成功了,特意记录下 首先先说明下vue-cli的assets和static的两个文件的区别, ...
- 认识Nginx
无论你用浏览器还是APP访问多数网站,到达的第一站就是Nginx. 后来者居上的Nginx 千禧年前后,互联网业务迎来了高速发展,老牌的Web服务器都无法满足高性能.高可靠的市场需求. 一个开源的(遵 ...
- Asp.Net Core 2.0实现HttpResponse中繁切换
随笔背景:因为项目中有个简单的功能是需要实现中文简体到繁体的切换,数据库中存储的源数据都是中文简体的,为了省事就想着通过HttpHeader的方式来控制Api返回对应的繁体数据. 实现方式:通过Asp ...
- 单链表反转的原理和python代码实现
链表是一种基础的数据结构,也是算法学习的重中之重.其中单链表反转是一个经常会被考察到的知识点. 单链表反转是将一个给定顺序的单链表通过算法转为逆序排列,尽管听起来很简单,但要通过算法实现也并不是非常容 ...