首页 > 其他分享 >10月24日用socketserver模块TCP和UDP的服务器

10月24日用socketserver模块TCP和UDP的服务器

时间:2023-10-24 20:24:20浏览次数:40  
标签:24 10 UDP socketserver self request 服务器 端口号 客户端

目录

socketserver模块

为什么要考虑这个模块呢?因为真实情况下不一定只有一个客户端连接,如果我使用socket模块就无法实现一个服务器连接多个客户端同时回复客户端的数据,下面先展示一下这个情况图

这个结果图就说明了这个问题,这里可以牵扯一些线程socket拿来给单线程挺好的如果给它应用到多线程算了没戏,所以就需要用socketserver这个模块来实现,多线程可以暂时理解为多个线程就可以有多个进程同时使用

TCP协议的服务器以及客户端

服务器的代码

#使用socketserver模块

#导入模块
import socketserver


#自己定义一个了类,必须继承BaseRequestHandler,这是一个固定的继承能不改就不改
class Mytcp(socketserver.BaseRequestHandler):
    #这里必须重写handle方法
    def handle(self):
        try:
            while True: #通信循环
                # 给客户端回复消息
                # conn对象就是request
                # 接收数据
                data = self.request.recv(1024)
                print(data)

                #这里给linux的操作系统做准备的
                if len(data) ==0:
                    return
                # 发送数据
                self.request.send(data.upper())#这里把收到的数据大写发送回去

        except Exception:
            pass

if __name__ == '__main__':
    #实例化得到一个tcp连接的对象,Threading意思是,只要来了请求,就会自动开启线程来处理连接跟交互数据
    #第一个参数是绑定的地址(元组的形式),第二个参数传一个类(自己定义的类)
    duixiang = socketserver.ThreadingTCPServer(('172.17.8.49', 8080), Mytcp)#如果没有客户端连接就会在这里等待
    #监听
    duixiang.serve_forever()#这里的serve_forever是一直监听的意思

这里来细讲服务器的代码

第一步:首先导入socketserver这个模块

第二步:然后在定义一个类(其实主要修改hanle函数这个方法就行了)同时要继承牵扯固定格式(socketserver.BaseRequestHandler)能不改就不改,因为要修改的函数就是它里面的方法,不要修改!!!

第三步:给修改的函数里面添加功能,这里面的接收数据和发送数据多了self.request这个代码,它是一个约定俗成的,通常不要修改,要是修改就会很麻烦,所以记住这个格式就行了。它是用来接收客户端发来的数据和发送响应给客户端的数据的套接字对象。

第四步:使用全局调用的方式来运行(也可以不用,随自己的想法来运行),这里面的socketserver.ThreadingTCPServer当做固定格式就好了它代表这个TCP服务器然后它里面要传两个参数,第一参数要以元组的形式来把IP地址以及端口号绑定上去,然后第二个参数来传自己定义的类来使用类里面的方法

第五步:监听启动服务器这里的监听格式是serve_forever(),到这步后服务器就正式启动了。

客户端可以用以前TCP客户端的形式

import socket

soc = socket.socket()

soc.connect(('172.17.8.49', 8080))

while True:
  
    soc.send('yyy'.encode('utf-8'))
    print(soc.recv(1024))

结果图如下

这是拿来测试的代码尽量别用上面的方式来输出和收取,否则电脑死机概不负责

那么这个模块会不会也有粘包问题,这是必定的因为现在它是按TCP协议来写的服务器

UDP协议的服务器以及客户端

UDP协议的服务器和TCP协议的服务器代码相差无几,只用修改几处即可

服务器

#UDP服务器(pro版的socketserver版)
import socketserver


#自己定义一个了类,必须继承BaseRequestHandler,这是一个固定的继承能不改就不改
class Mytcp(socketserver.BaseRequestHandler):
    #这里必须重写handle方法
    def handle(self):
        print(self)

        #数据部分的处理
        #这时候request就是客户端发来的元组里面有数据有IP地址和端口号了
        #然后这是第一种方法赋值
        data, addr = self.request
        print(data.decode('utf-8'))#这是客户端发过来的数据同时给它进行解码的操作
        print(addr)#这是客户端的IP地址以及使用端口号的数据



        # #这是第二种方法索引
        # print(self.request[0])#这是客户端发过来的数据
        # print(self.request[1])#这是客户端

      


        #回复客户端的数据请求
        shuru = input('请输入回复的数据:')
        self.request[1].sendto(shuru.encode('utf-8'),self.client_address)





if __name__ == '__main__':
    
    #第一个参数是绑定的地址(元组的形式),第二个参数传一个类(自己定义的类)
    duixiang = socketserver.ThreadingUDPServer(('172.17.8.49', 8080), Mytcp)#如果没有客户端连接就会在这里等待
    # #监听
    duixiang.serve_forever()#这里的serve_forever是一直监听的意思

这个UDP服务器代码里面的监听必须要用

同时将socketserver.ThreadingUDPServer当做固定格式就好了它代表这个UDP服务器然后它里面要传两个参数,第一参数要以元组的形式来把IP地址以及端口号绑定上去,然后第二个参数来传自己定义的类来使用类里面的方法

这个UDP服务器是不需要使用recvfrom(1024)来收取客户端的数据,self.request它就是客户端发来的数据同时这里面还有客户端的IP地址以及端口号(IP地址和端口号是在一个元组里)

然后如何查看客户端发来的数据以及IP地址和端口号呢?

有两个方法
第一个是将数据、IP地址和端口号的所在的元组分别进行赋值到其它的变量里来查看和使用
第二个是利用索引的方法来查看和使用
这两个方法代码里面都有

然后客户端的代码如下

import socket

client = socket.socket(type=socket.SOCK_DGRAM)

while True:
    msg = input('输入请求:')
    client.sendto(msg.encode('utf-8'), ('172.17.8.49', 8080))

    data,ader = client.recvfrom(1024)

    print(data.decode('utf-8'))

这个代码没什么可讲的

修改UDP修改版

在和其它电脑测试中无法正确读取别人的IP地址和端口号,所以进行了修改:使用了self.client_address的方法来将IP地址和端口号它们两个的元组给拆开分别赋值,IP地址赋值给了client_IP,端口号赋值给了client_PORT

修改代码如下

#UDP服务器(pro版的socketserver版)
import socketserver


#自己定义一个了类,必须继承BaseRequestHandler,这是一个固定的继承能不改就不改
class Mytcp(socketserver.BaseRequestHandler):
    #这里必须重写handle方法
    def handle(self):

        #数据部分的处理
        #这时候request就是客户端发来的元组里面有数据有IP地址和端口号了
        #然后这是第一种方法赋值
        data, addr = self.request#addr数据不是客户端的
        print(data.decode('utf-8'))#这是客户端发过来的数据同时给它解码的操作
        

        #获取客户端的IP地址和端口号
        client_IP, client_PORT = self.client_address
        print(f'客户端的IP地址是{client_IP}它使用的端口号为{client_PORT}')


        # #这是第二种方法索引
        # print(self.request[0])#这是客户端发过来的数据
        # print(self.request[1])#这是客户端




        #回复客户端的数据请求
        shuru = input('请输入回复的数据:')
        self.request[1].sendto(shuru.encode('utf-8'),self.client_address)





if __name__ == '__main__':
    #实例化得到一个tcp连接的对象,Threading意思是,只要来了请求,就会自动开启线程来处理连接跟交互数据
    #第一个参数是绑定的地址(元组的形式),第二个参数传一个类(自己定义的类)
    duixiang = socketserver.ThreadingUDPServer(('172.17.8.49', 8080), Mytcp)#如果没有客户端连接就会在这里等待
    # #监听
    duixiang.serve_forever()#这里的serve_forever是一直监听的意思

客户端的不用修改,正常使用

最后效果如图

标签:24,10,UDP,socketserver,self,request,服务器,端口号,客户端
From: https://www.cnblogs.com/slzjb/p/17785666.html

相关文章

  • 基于ZCU104的PS和PL数据交互例程(三):vivado中创建IP
    基于ZCU104的PS和PL数据交互例程(三):vivado中创建IP以创建带有AXI-LITE接口的IP为例子按照下面步骤创建这里注意,这里选择的NumberofRegisters,会在后面的代码里面对应slv_reg0,slv_reg1,...,slv_reg3打开IP目录,右键刚才的IP,选择EidtinIPPackagercontroller_v1_0......
  • 多年学习django经验markdown总结,基础到高手,共计50页,10大模块。 第(1)期
    Django的主要目的是简便、快速的开发数据库驱动的网站。它强调代码复用,多个组件可以很方便的以"插件"形式服务于整个框架,Django有许多功能强大的第三方插件,你甚至可以很方便的开发出自己的工具包。这使得Django具有很强的可扩展性。它还强调快速开发和DRY(DoNotRepeatYourself)原......
  • 文心一言 VS 讯飞星火 VS chatgpt (120)-- 算法导论10.3 5题
    五、用go语言,设L是一个长度为n的双向链表,存储于长度为m的数组key、prev和next中。假设这些数组由维护双链自由表F的两个过程ALLOCATE-OBJECT和FREE-OBJECT进行管理。又假设m个元素中,恰有n个元素在链表L上,m-n个在自由表上。给定链表L和自由表F,试写出一个过程......
  • 2024届毕业-找工作历程
    学历:双非硕士  研究方向:基于深度学习的滚动轴承故障诊断  2024年应届毕业生掌握语言:Python1.2023/09/10 投递   长鑫存储  ---微信公众号投递 研发技术类 产品认证与测试 学历要求:硕士  -----已凉研发技术类 缺陷分析研发(J12777)硕士   ......
  • 231023校内赛
    T1区间题解很容易想到的一点是如果\(k\)足够大,那么把区间单独放到一个组里总比多个区间在一个组优对于多个区间来说,区间之间如果两两不包含的话这道题会是比较好做的就可以注意到如果一个大区间包含了一个小区间,那么大区间要么单独一组,要么和小区间同一组,这样会是比较优的......
  • ARC102
    A枚举其中一个,然后发现剩下两个的限制非常强,用一个桶统计同余类大小即可。B谔谔构造。考虑\(n=\log10^6\),大概可以猜一下这个题是想让我们搞一个二进制构造。先造一条\(0\sim2^{\logL}-1\)的链,然后再往\(N\)连即可。C基础组合题。不是很懂为啥题解里都是容斥原理,范......
  • 1024程序员节,我们来点轻松的,拼手速截图看看你是哪种type的程序员!
    “爱码士”们来拼手速!云宏君今日也是“需求加载中“,与身边的it小伙伴一起来找标签吧......
  • 10.23
    今天学习mybatis实现增删改查  ......
  • 10.24日记
    CPU 计算机硬件基本系统有五大部分组成:运算器,控制器,存储器,输入设备,输出设备。 存储器分为内部存储器(即内存,容量小,速度快,临时存放数据)和外部存储器(即硬盘,光盘等,容量大,速度慢,长期保存数据) 中央处理单元组成:由运算器,控制器,寄存器组和内部总线组成 中央处理单元功能:实现程序控制,操......
  • 10.20
    1、今天学习了数据库连接池, 2、学习lombok实现javabean的简便开发 ......