上一篇主要实现了消息的收和发,但不能同时进行,这太不科学了。这次学的是发消息的同时还能收消息。
一,首先我要实现的是功能就是收消息和发消息。可以啊,那就给这两个功能分别定义函数啊,于是就有了下面的代码。
def udpsend(): #先把两个函数定义出来
pass #具体实现步骤,先不写,想一想,先用pass代着,保持程序完整性
def udprecv():
pass
def main():
udpsend() #这里先这样写,后面再完善,线程还没有导入,这样肯定是没法同时进行的
udprecv()
if __name__ == '__main__': #整个程序运行一个主进程,等两个子线程完成。
main()
二,框架出来了,再来完善细节。细节就联系到前面的内容了,怎么发,发给谁,发什么,然后多一个怎么同时进行。
1,先来完善发送的函数里面的内容。
def udpsend():
sendaddr = ("172.20.10.3",8877) # 确定发送ip地址和端口(解决发给谁的问题)
while True: #我们不想聊一次就结束了,还有好多话要说,所以就加一个while
senddata = input('<<') # 要发送的信息(解决发什么的问题)
udpsocket.sendto(senddata.encode("gb2312"), sendaddr) # 发送信息,这里用Gb2312编码是因为网络调试助手是用GB2312编码的。通常用utf-8编码。
2,再完善收消息的函数内容。这里和以往不同的是,打印消息用的不是print,而是write。因为print出来内容,在末尾是自动加了一个“n”,所以每打印一次就换行了。这里我们不仅需要换行,而且需要将前面的“<<”换成“>>”,所以要将光标定位到行首,并将打印的内容刷新出来。
def udprecv():
while True:
result = udpsocket.recvfrom(1024) #每次接收1024个字节
sys.stdout.write('r%s%sn' % (">>", result[0].decode("gb2312")))
sys.stdout.flush() #这里用刷子是为了将消息的引导箭头改变,不然两个箭头就重合了。
sys.stdout.write("r%s" % ('<<')) #为了实现打印完接收的信息,出现输入的标志
sys.stdout.flush()
3,两个主函数已经定义完了,现在要实现一个更重要的功能了,怎么让两个功能同时实现,既可以收,又可以发。多线程上场了。
def main():
thread_send = Thread(target=udpsend) #分配发消息的线程
thread_recv = Thread(target=udprecv) #分配收消息的线程
thread_send.start() #线程创建好了,让线程一同开始
thread_recv.start()
thread_send.join() #这里还可以设置时间
thread_recv.join()
4,多线程也设置完毕了,主要工作都结束了,到了最后完善细节了,缺什么补什么。线程模块还没导入,系统模块没有导入,连套接字用还没有导入和创建。补!
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()
就都结束了,看看效果