zoukankan      html  css  js  c++  java
  • 1.工具开发socket编程技术

    socker编程技术

    socket--一对一

    • TCP协议与UDP协议
      • TCP(transmission control protocol)可靠的,面向连接的协议(eg:打电话)、传输效率低,全双工通信(发送缓存&接收缓存)、面向字节流。使用TCP的应用:web浏览器、电子邮件、文件传输等
      • UDP(user datagram protocol)不可靠的,无连接的服务,传输效率高(发送前时延小),一对一、一对多、多对一、多对多、面向报文,尽最大努力服务,无拥塞控制。使用UDP的应用:域名系统(DNS);视频流;IP语音(volp)--反正数据给你了,不管你拿不拿到

    图 2

    • websocket基于应用层协议---HTTP

    • socket基于传输层协议---TCP

    • socket工作原理

    图 1

    • 1、服务器根据地址类型、socket类型、协议创建socket

    • 2、服务器为socket绑定ip地址和端口号

    • 3、服务器socket监听端口号请求,随时准备接收客户端发来的连接,这时候服务器的socket并没有打开

    • 4、客户端创建socket

    • 5、客户端打开socket,根据服务器IP地址和端口号试图连接服务器socket

    • 6、服务器socket接收到客户端socket请求,被动打开,开始接收客户端请求,知道客户端返回连接信息。这时候socket进入阻塞状态,所谓阻塞即accept()方法一直等到客户端返回连接信息后返回,开始接收下一个客户端的连接请求

    • 7、客户端连接成功,向服务器发送连接状态的信息

    • 8、服务器accept方法返回,连接成功

    • 9、客户端向socket写入信息(或服务端向socket写入信息)

    • 10、服务器读取信息(客户端读取信息)

    • 11、客户端关闭

    • 12、服务端关闭

    • socket的常用方法

    • 低级别的网络服务支持基本的socket,它提供了标准的SBD socket API,可以访问底层操作系统socket接口的全部方法

    • 高级别的网络服务模块socketserver,他提供了服务器中心类,可以简化网络服务器的开发

    • 什么是socket编程

      • socket又称套接字,应用程序通常通过套接字向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯
        socket函数
        python中,我们用socket()函数来创建套接字,语法格式如下
      socket.socket([family[,type[,proto]]])
      
      参数
        * family:套接字家族可以使用AF_UNI或者AF_INET.
        * type:套接字类型可以根据是面向连接还是非连接分为SOCK_STREAM或SOCK_DGRAM.
        * protocol:一般不填默认为0
      
    • socket服务端

      • 使用socket模块的socket函数来创建一个socket对象,socket对象可以通过调用其他函数来设置一个socket服务
      • 可以通过调用bind(hostname,port)函数来指定服务的port(端口)
      • 调用socket对象的accept方法,该方法等待客户端的连接,并返回connection对象,表示客户端已经连接到服务端
    • socket客户端

      • socket。connect(hostname,port)方法打开一个TCP,连接到主机为hostname,端口为port的服务端
      • 连接后就可以从服务端获取数据,记住,操作完成后需要关闭连接

    socket代码

    服务端代码:

            import socket
            ip_port=('127.0.0.1',8888)
            #1-创建socket对象
            sk=socket.socket()
            #2-绑定ip port
            sk.bind(ip_port)
            #3-启动监听
            sk.listen()
            print('---服务器上线了---')
            # 4-阻塞等待连接 返回 套接字 和 客户端的IP
            conn,addr =sk.accept()
            print('客户端的地址>>>:',addr)
            #5-接收数据
            client_data =conn.recv(1024).decode('utf-8')
            print('接收到客户端的数据>>>',client_data)
            #6-发送数据
            send_data = input('请输入>>>')
            conn.sendall(send_data.encode('utf-8'))
            print('发送给客户端的数据>>>',send_data)
            #7-关闭socket
            conn.close()
    

    客户端代码

            import socket
            ip_port=('127.0.0.1',8888)
            #1-创建socket对象
            sk=socket.socket()
            #2-建立连接
            sk.connect(ip_port)
            #3-发送数据
            send_data =input('请输入>>>')
            sk.sendall(send_data.encode('utf-8'))
            print('发送给服务端的数据>>>',send_data)
            #4-接收数据
            server_data =sk.recv(1024).decode('utf-8')
            print('接收到服务端的数据>>>',server_data)
            #5-关闭socket
            sk.close()
    
    

    局限:只能一对一聊天,不能多对多聊天

    socketserver--一对多

    socketserver代码

    服务端:

    import socketserver
    #1-需要继承一个类BaseRequestHandler 实现handle方法
    print('---服务启动完成,等待客户端中---')
    class SKserver(socketserver.BaseRequestHandler):
        def handle(self):
            print('---有客户端上线了---')
    
            #处理逻辑,self.request方法
            while True:
                #接收数据
                client_data =self.request.recv(1024).decode('utf-8')
                print('接收到客户端的数据>>>',client_data)
                #发送数据
                send_data=input('请输入:>>>')
                self.request.sendall(send_data.encode('utf-8'))
                print('发送给客户端的数据>>>',send_data)
            self.request.close()
    #2-创建服务,多线程方式ThreadingTCPServer
    sk=socketserver.ThreadingTCPServer(('127.0.0.1',8888),SKserver)
    #3-保持一直在线
    sk.serve_forever()
    

    客户A 客户B复制A的代码

    import socket
    ip_port=('127.0.0.1',8888)
    #1-创建socket对象
    sk=socket.socket()
    #2-建立连接
    sk.connect(ip_port)
    while True:
        #3-发送数据
        send_data =input('a:'+'请输入>>>')
        sk.sendall(send_data.encode('utf-8'))
        print('发送给服务端的数据>>>',send_data)
        #4-接收数据
        server_data =sk.recv(1024).decode('utf-8')
        print('接收到服务端的数据>>>',server_data)
    #5-关闭socket
    sk.close()
    

    运行结果
    图 4
    客户端A:

        a:请输入>>>a
        发送给服务端的数据>>> a
        接收到服务端的数据>>> aa
        a:请输入>>>aaa
        发送给服务端的数据>>> aaa
        接收到服务端的数据>>> aaaa
        a:请输入>>>
    

    客户端B:

        b:请输入>>>b
        发送给服务端的数据>>> b
        接收到服务端的数据>>> bb
        b:请输入>>>bbb
        发送给服务端的数据>>> bbb
        接收到服务端的数据>>> bbbb
        b:请输入>>>
    

    问题记录

    • 1、TypeError: recv() takes at least 1 argument (0 given)

      client_data =conn.recv()
      TypeError: recv() takes at least 1 argument (0 given)
      
      • 原因分析:
        • 未指定接收数据大小
      • 解决方法
        • 指定数据大小
        • client_data =conn.recv(1024)
    • 2、TypeError: a bytes-like object is required, not 'str'

      sk.sendall(send_data)
      TypeError: a bytes-like object is required, not 'str'
      
      • 原因分析:
        • 未指定编码格式,需要字节流而不是字符串
      • 解决方法
        • 指定编码格式为utf-8
        • sk.sendall(send_data.encode('utf-8'))
    • 3、OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。

        self.socket.bind(self.server_address)
        OSError: [WinError 10048] 通常每个套接字地址(协议/网络地址/端口)只允许使用一次。
      
      • 原因分析:
        • 当我们在PyCharm中把运行窗口中运行状态终结了,实质是执行的python程序还没有结束, 所以打开windows任务管理器,把名为python的进程统统结束。
      • 解决方法
        • 任务管理器,关闭python运行程序
          图 3
  • 相关阅读:
    GO学习-(17) Go语言基础之反射
    Go语言基础之time包
    Go语言标准库log介绍
    GO学习-(16) Go语言基础之文件操作
    GO学习-(15) Go语言基础之包
    GO学习-(14) Go语言基础之接口
    五种开源API网关实现组件对比
    Spring Junit4 Test
    Java泛型
    SQL 基本(Head First)
  • 原文地址:https://www.cnblogs.com/xiehuangzhijia/p/14969200.html
Copyright © 2011-2022 走看看