python网络编程arp_python之网络编程-udp协议(三)

将上面的一个收发消息程序再封装一次,面向对象编程。先贴出上一篇整理的代码:

from socket import *     #补
from threading import Thread    #补
import sys                             #补
def udpsend():
    sendaddr = ("172.20.10.3",8877)  # 确定发送ip地址和端口
    while True:
        senddata = input('<<')  # 确定要发送的信息
        udpsocket.sendto(senddata.encode("gb2312"), sendaddr)  # 发送信息,这里用Gb2312编码是因为网络调试助手是用GB2312编码的。通常用utf-8编码。
def udprecv():
    while True:
        result = udpsocket.recvfrom(1024)
        sys.stdout.write('r%s%sn' % (">>", result[0].decode("gb2312")))
        sys.stdout.flush()
        sys.stdout.write("r%s" % ('<<'))
        sys.stdout.flush()
udpsocket = None                 #补
def main():
    global udpsocket           #补,因为接受和发送都需要用到套接字,所以要全局化
    udpsocket = socket(AF_INET, SOCK_DGRAM)  # 创建套接字,现在用的是udp,还有一种tcp
    udpsocket.bind(("", 5566))     #补,绑定端口,接收消息
    thread_send = Thread(target=udpsend)
    thread_recv = Thread(target=udprecv)
    thread_send.start()
    thread_recv.start()
    thread_send.join()
    thread_recv.join()
if __name__ == '__main__':
    main()

这么多代码,怎么封装呢?把什么提出来做属性和方法?

还是回到了起点。我们要实现什么?----我们就是想实现发消息和收消息这个功能,恩,那这两个就是要定义的方法。还要同时进行啊,还那封装到另一个方法里调用。那属性是什么呢?想了半天,我知道了谁的ip,port和自己要绑定的port,就可以和他聊天了啊,也就是传这三个参数就可以了。

from socket import *
from threading import Thread
import sys
class Simutalk(object):
    def __init__(self,sendaddr,port):   #绑定属性
        self.sendaddr = sendaddr
        self.port = port
    def udpsend(self):    #定义发送消息函数
        while True:
            self.senddata = input('<<')  # 确定要发送的信息
            self.udpsocket.sendto(self.senddata.encode("gb2312"), self.sendaddr)  # 发送信息,这里用Gb2312编码是因为网络调试助手是用GB2312编码的。通常用utf-8编码。
    def udprecv(self):
        while True:
            self.result = self.udpsocket.recvfrom(1024)
            sys.stdout.write('r%s%sn' % (">>", self.result[0].decode("gb2312")))
            sys.stdout.flush()
            sys.stdout.write("r%s" % ('<<'))
            sys.stdout.flush()
    def threads(self):    #定义多线程函数,调用收发消息函数
        self.crea_socket()
        self.thread_send = Thread(target=self.udpsend)
        self.thread_recv = Thread(target=self.udprecv)
        self.thread_send.start()
        self.thread_recv.start()
        self.thread_send.join()
        self.thread_recv.join()
    def crea_socket(self):    #这里我把剩下的都放一起了。。。其实我也不知道合不合适,不过是对的
        self.udpsocket = socket(AF_INET, SOCK_DGRAM)  # 创建套接字,现在用的是udp,还有一种tcp
        self.udpsocket.bind(("", self.port))

调用结果:

import Socket7    #导入模块要在一个路径导,不然找不到的(上一个程序的名字我命名为Socket7)
firsttalk = Socket7.Simutalk(("172.20.10.3", 8877),5566) #实例化,传三个参数(目标ip,port,我要绑定的port)
firsttalk.threads()

b0a6cba02f12ca773f1bea76ca5a2d24.png

绑定port的问题是,如果没有绑定,但是我先给对方发消息,它有了我的ip和port之后是可以和我发消息的;要是我没有绑,对方是没法先给我发消息的,因为它不知道我的port。


对上面的代码稍作更改,只是结构上的,上面代码运行起来也没有问题。(下面这段代码不作模块导入使用,要作为模块使用需要更改main函数位置)

#coding = utf-8
from socket import *
from threading import Thread
import sys
class Simutalk(object):    
    def __init__(self):   #这里做了一点改变,简化实例化时传参的过程
        self.udpsocket = socket(AF_INET, SOCK_DGRAM)  # 创建套接字,现在用的是udp,还有一种tcp
        self.sendaddr = (input("请输入对方ip:"), int(input("请输入对方端口:")))
    def udpsend(self):
        while True:
            self.senddata = input('<<')  # 确定要发送的信息
            self.udpsocket.sendto(self.senddata.encode("gb2312"), self.sendaddr)  # 发送信息,这里用Gb2312编码是因为网络调试助手是用GB2312编码的。通常用utf-8编码。
    def udprecv(self):
        while True:
            self.result = self.udpsocket.recvfrom(1024)
            sys.stdout.write('r%s%sn' % (">>", self.result[0].decode("gb2312")))
            sys.stdout.flush()
            sys.stdout.write("r%s" % ('<<'))
            sys.stdout.flush()
    def threads(self):
        self.thread_send = Thread(target=self.udpsend)
        self.thread_recv = Thread(target=self.udprecv)
        self.thread_send.start()
        self.thread_recv.start()
        self.thread_send.join()
        self.thread_recv.join()
    def bind(self, port):
        self.udpsocket.bind(("", port))
def main():
    simutalk = Simutalk()
    simutalk.bind(7788)   #这里做了改变,为了简化传参,将端口拿出来通过bind函数绑定
    simutalk.threads()
if __name__ == '__main__':
    main()

更改的主要思想是:

一,练习创建接口,通过调用主函数实现整个程序的运行。

二,将一开始就要用到的或者需要创建的变量放到构造函数里完成,比如上面的,就省去了最后还要定义create_socket(self)函数的步骤。

三,一定要注意整体结构,这里main()和class()是并列的,是为了就在当前界面运行看结果,如果想要导入模块使用,就要改下了,不然会有点小问题。

下面代码作为模块导入

from socket import *
from threading import Thread
import sys
def main():
    class Simutalk(object):
        def __init__(self):
            self.udpsocket = socket(AF_INET, SOCK_DGRAM)  # 创建套接字,现在用的是udp,还有一种tcp
            self.sendaddr = (input("请输入对方ip:"), int(input("请输入对方端口:")))
        def udpsend(self):
            while True:
                self.senddata = input('<<')  # 确定要发送的信息
                self.udpsocket.sendto(self.senddata.encode("gb2312"),
                                      self.sendaddr)  # 发送信息,这里用Gb2312编码是因为网络调试助手是用GB2312编码的。通常用utf-8编码。
        def udprecv(self):
            while True:
                self.result = self.udpsocket.recvfrom(1024)
                sys.stdout.write('r%s%sn' % (">>", self.result[0].decode("gb2312")))
                sys.stdout.flush()
                sys.stdout.write("r%s" % ('<<'))
                sys.stdout.flush()
        def threads(self):
            self.thread_send = Thread(target=self.udpsend)
            self.thread_recv = Thread(target=self.udprecv)
            self.thread_send.start()
            self.thread_recv.start()
            self.thread_send.join()
            self.thread_recv.join()
        def bind(self, port):
            self.udpsocket.bind(("", port))
    simutalk = Simutalk()
    simutalk.bind(7788)
    simutalk.threads()
if __name__ == '__main__':
    main()

调用效果

bca8b97b14cbc36eaaed995e12698380.png
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值