zoukankan      html  css  js  c++  java
  • 基于socket简易版客户端,服务端交互

    简易版客户端服务端交互

    常识

    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循环 ,但是我们的服务端也需要一直接受信息,否则发信息就没有意义了

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

      1567775794109

    这个时候就需要加上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)
    
    
  • 相关阅读:
    遗忘
    2008年第一篇1.15
    键盘对应值
    油田开采基础知识
    最近
    oracle中lob数据的操作
    [转]大数据能做什么,大数据和云是不是一回事?
    [转]从这些方面判断一家公司的好坏
    This Android SDK requires Android Developer Toolkit version 20.0.0 or above
    谈创新
  • 原文地址:https://www.cnblogs.com/jhpy/p/11503668.html
Copyright © 2011-2022 走看看