码迷,mamicode.com
首页 > 其他好文 > 详细

基于socket简易版客户端,服务端交互

时间:2019-09-10 23:27:25      阅读:95      评论:0      收藏:0      [点我收藏+]

标签:粘包   直接   属性   接受   tcp协议   end   coding   src   协议   

简易版客户端服务端交互

常识

AF_UNIX 是基于文件类型的套接字家族
AF_INET是 基础网络类型的套接字家族
socket 模块属性很多,可以直接使用from module import *语句 ,这样socket所有的数据都被带劲命名空间里了. 减少代码量(少用)

服务端

#1导入
import socket
# 2.获取套接字
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#3绑定
s.bind(('127.0.0.1',8070))
#4开机,监听
s.listen(1)
#5创建一个通道和地址,等待接受电话

conn,addr=s.accept()
#6接受这个值
data=conn.recv(1024)
#7释放数据
print(data)
#8用通道发送数据
conn.send('帅逼'.encode('gbk'))
#9关闭通道
conn.close()
#10关闭服务端
s.close()
             

客户端

#导入
import socket
#创建对象
s=socket.socket()
#连接服务端地址
s.connect(('127.0.0.1',8070))
s.send(b'adas')
#接受字节数据
data=s.recv(1024)
#打印展现出来
print(data.decode('gbk'))
#关闭
s.close()

 

基础知识混淆点


把b格式转成字符串
ss=str(b'hello',encoding='utf8')
等于这个
ss=b'hello'.decode('utf8')

把字符串转成b格式
by=bytes('hello',encoding='utf8')
by='hello'.encode('utf8')

解决客户端突然断开连接

客户端需要发信息一直发信息 所以有while循环 ,但是我们的服务端也需要一直接受信息,否则发信息就没有意义了

  • 但是 如果说客户端突然断开连接这个时候就会出现一下错误

    技术图片

这个时候就需要加上==try 以及 except EXCEPTION== 如果出现了错误 ,那么咱们需要怎么做。。

==总结==:

服务端server

#1导入
import socket
# 2.创建对象
s=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
#3绑定
s.bind(('127.0.0.1',8070))
#开机,监听
s.listen(1)
#创建一个通道和地址,等待接受电话
conn,addr=s.accept()
#接受这个值
while True:
    try:
        #等待接受  最大收1024字节
        data=conn.recv(1024)
    #释放数据
        print(data.decode('utf8'))
    except Exception:
        conn.close()
        break

client 客户端

导入 创建 连接 发送信息 转换格式

import socket
#创建新对象
s=socket.socket()
#连接直接用
s.connect('127.0.0.1',8070)
#发送信息
while True:
    msg=input('输入')
    #发送输入数据
    s.send(msg.encode('utf8'))    
    

套接字加上连接循环通讯循环

服务端要一直稳定的运行,不能客户端断了 咱们的服务端等着连接的代码需要重写一遍,所以应该==让服务端循环等着客户端的连接==(但是接受,打印客户数据信息,需要在连接之后写)所以需要加上一个循环嵌套,==循环嵌套是 内层嵌套运行break掉才会继续运行外层循环的信息==(称之为结算运行)。

==需求精简==:服务端要能够一直的循环等待客户端连接,蛋不需要发一次信息就连接一次。

==实现精简==:嵌套循环 等待客户端连接代码写在大循环,接受客户数据信息,与打印信息放在内层循环里面。

……
#接受这个值
while True:
    print('等待客户端的连接')
    conn,addr=s.accept()
    while True:
        try:
            #等待接受  最大收1024字节
            data=conn.recv(1024)
        #释放数据
            print(data.decode('utf8'))
        except Exception:
            conn.close()
            break
    conn.close()

addr是客户端的地址

解决粘包问题

基础概念

TCP粘包就是指发送方发送的若干个包数据 --->接收方接受时粘成一个包,两个数据包是有数据头尾的,后一个包可能会紧接着前一个包的尾

可能是发送方造成的,也可能是有接收方造成的,发送方因其粘包是有TCP协议本身造成的,如果==连续几次发送数据很少,那么TCP会根据优化算法把这些数据合成一个包后一次发送出去==,这样接收方就收到了粘包数据。

解决方案

长度不变,就不会粘包,因为粘包,发送方或者接收方可能会少数据多数据,固定他的字节的长度就不会产生粘包

struct模块

为字节流加上自定义固定长度报头,报头中包含字节流长度,然后一次send到对端,对端在接收时,先从换从中取出定长的报头,然后打开包裹取真实数据,

主要是把一个类型转成固定长度的bytes。核心

步骤

导包-->打包Pack(‘模式‘,数据)--解包

# 导报#
import struct
#打包创建对象里面有模式(以字符串表示),跟这个数据对象
obj=struct.pack('i',1234532111)
print(obj)
print(len(obj))  #固定4个字节的长度
#打开包裹,反解出来
l=struct.unpack('i',obj)[0]#是一个小元祖 取索引第0个
print(l)

基于socket简易版客户端,服务端交互

标签:粘包   直接   属性   接受   tcp协议   end   coding   src   协议   

原文地址:https://www.cnblogs.com/jhpy/p/11503668.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!