python socket通信多线程_python 实现 udp socket 编程的多线程问题

希望实现以下功能:

在点击“启动服务器”,即执行start函数时,开启监听线程,监听线程会用recvfrom()函数来监听数据报的到来。但是如果没有数据报过来,则其会阻塞在recvfromm()上。但是希望在没有数据报来的时候,可以继续主进程(会发送数据报的进程)的执行。

求问怎么做??

具体两个函数如下:(给出了前面主要的函数,剩下的一些省略了)

from tkinter import *

from time import sleep

from UserTable import *

from RoomTable import *

from ServerReceive import *

from socket import *

import pickle

import re

import string

import time

import threading

import pdb

用于建立服务端界面,建立监听线程,并处理本地命令

root = Tk()

root.geometry("600x400")

root.title("服务器端")

userroot = UserInfo(0, '', '', 0)

userTable = UserTable(userroot, None, 0) #用户列表

roomTable = RoomTable( ) #竞拍室列表

InRoom = None

text_contents=''

host = '127.0.0.1'

port =7890

nums = string.digits

发送按键对应的函数

def Send():

text_contents = text.get()

listbox.insert(END, text_contents)

text.delete(0,END)

cmd_choice(text_contents)

启动按键对应的函数,服务器端启动

def Start():

try:

global server

server = socket(AF_INET, SOCK_DGRAM) #启动服务端socket,默认端口7890

server.bind((host, port))

listbox.insert(END, "服务器端启动" )

#pdb.set_trace()

serverrec = ServerReceive(server, listbox, userTable, roomTable)

#pdb.set_trace()

serverrec.start() #建立监听线程???

serverrec.join()

except:

Exception, e

print(e)

退出按键对应的函数.服务器端退出

def Exit():

SendMsg("/msg 【系统消息】 服务器关闭!")

exit()

进行命令匹配的函数

def cmd_choice(text_contents):

m=re.match("/msg ", text_contents)

if m: #群发消息

SendMsg(text_contents)

else:

m=re.match("/list", text_contents) #列出某竞拍室情况

if m:

List()

else:

m=re.match("/kickout ", text_contents) #将某竞拍者踢出拍卖室

if m:

Kickout(text_contents)

else:

m=re.match("/opennewauction ", text_contents) #开通新竞拍室

if m:

Open(text_contents)

else:

m=re.match("/auctions", text_contents) #列出所有竞拍室情况

if m:

Auction()

else:

m=re.match("/enter ", text_contents) #加入某竞拍室

if m:

Enter(text_contents)

else:

m=re.match("/leave", text_contents) #离开某竞拍室

if m:

Leave()

else:

m=re.match("/close ", text_contents) #关闭某竞拍室

if m:

Close(text_contents)

else: #其他格式错误命令,弹出警告框??

listbox.insert(END, "\t命令输入错误!")

命令/msg [bidderID],群发和向指定用户发送消息

def SendMsg(text_contents):

lenmsg = len(text_contents)

if lenmsg == 4 or lenmsg == 5: #命令中没有发送内容,警告

listbox.insert(END, "未输入发送消息的内容!\n" )

return

i = 7

if text_contents[5] == "[" and text_contents[6] in nums: #对某一用户发送消息 查找用户ID

while text_contents[i] in nums:

i=i+1

if text_contents[i] != "]":

listbox.insert(END, "\t命令输入错误!" ) #未输入用户ID,提示错误

return

ID = text_contents[6:i] #提取用户ID

temp = userTable.findUser(ID)

if temp : #在用户列表中找到该用户??

if i+1 == lenmsg:

listbox.insert(END, "未输入发送消息的内容!\n" ) #命令中没有发送内容,警告

return

message = text_contents[i+1:] + "\n" #提取发送内容

try: #发送内容???

server.sendto(message, temp.addr, temp.port)

except:

Exception,e

print (e)

else:

listbox.insert(END, "没有该用户!\n" ) #未在用户列表中找到该用户,警告

return

else: #对所有用户群发消息

message = text_contents[i+1:] + "\n"

temp = userTable.root

while temp.next != None: #遍历用户列表并发送消息

temp = temp.next

try: #发送内容???

server.sendto(message, temp.addr, temp.port)

except:

Exception, e

print (e)

命令/list,列出某一竞拍室参加竞拍者的情况(必须已进入某一竞拍室)

def List():

————————————————————————————————————————————

监听线程如下:

import re

import string

import threading

import pickle

from tkinter import *

from socket import *

from UserTable import *

from RoomTable import *

import pdb

类ServerReceive 网络拍卖行服务端监听接收线程类

用于监听并接收客户端发送过来的数据包,并进行相应的处理

class ServerReceive(threading.Thread):

server = socket(AF_INET, SOCK_DGRAM)

addr=''

port=0

ADDR=(addr,port)

recvStr=''

newStr=''

root=UserInfo(0, '', '', 0)

userList = UserTable(root, None, 0) #用户列表

roomTable = RoomTable() #竞拍室列表

bufsize=512

user = UserInfo(0, '', '', 0) #用户信息

room = RoomInfo('', 0) #竞拍室信息

bidderID = 1 #分配的用户ID

listbox = None

def __init__(self, server, listbox, userList, roomTable):

super().__init__()

self.server = server

self.listbox = listbox #消息接收区域

self.userList = userList

self.roomTable = roomTable

#启动监听并接收数据包,并对数据包进行处理

def run(self):

pdb.set_trace()

#i=0

while True:

#if i >= 1:

#break

try:

self.recvStr, self.ADDR = self.server.recvfrom(self.bufsize) #提取数据报内容,用户IP地址,端口号

self.user = self.userList.findUser(self.addr, self.port) #在用户列表中查找该用户信息

#socket.settimeout(self.server)

self.recvStr = self.recvStr.decode('gb2312')

#i+= 1

m=re.match("/login ", self.recvStr)

if m: #登录服务器

self.Login(self.recvStr,self.ADDR)

else:

m=re.match("/exit", self.recvStr) #退出

if m:

self.Exit()

else:

if user == None: #未登录(此时不允许输入除登录、退出之外的命令)

self.NoLogin()

else:

m=re.match("/auctions", self.recvStr) #列出所有竞拍室情况

if m:

self.Auctions()

else:

m=re.match("/list", self.recvStr) #列出某竞拍室情况

if m:

self.List()

else:

m=re.match("/join ", self.recvStr) #加入某竞拍室

if m:

self.Join(self.recvStr)

else:

m=re.match("/bid ", text_contents) #出价

if m:

self.Bid(self.recvStr)

else:

m=re.match("/leave", self.recvStr) #离开某竞拍室

if m:

self.Leave()

else: #其他格式错误命令

self.ErrorCom()

except:

Exception,e

print(e)

#命令格式错误

def ErrorCom(self):

error = "命令输入错误!\n"

try: #发送内容???

self.server.sendto(error, self.addr, self.port)

except:

Exception, e

print (e)

#命令/login bidderName,用bidderName登录服务器。服务方给该用户分配一个唯一标识bidderID

def Login(self, recvStr,ADDR1):

pdb.set_trace()

if len(recvStr) == 7: #命令不包含用户名

newStr = "未输入用户名!\n"

else:

name = recvStr[7:]

print(name)

if self.userList.findUser1(name) == None and self.user == None:

self.user = UserInfo(self.bidderID, name, self.addr, self.port) #加入新用户信息

self.userList.addUser(self.user)

self.listbox.insert(END, "用户 " + name + " 连接成功! " + str(ADDR1)+ "\n")

self.bidderID+= 1

newStr ="【系统消息】 您好,"+ name + ",欢迎来到网络拍卖行" + "! 您的用户ID: " + str(self.bidderID) + "\n" #返回欢迎信息

else:

if self.userList.findUser(self.addr, self.port)!= None: #该IP地址和端口已经登录过用户

newStr = "不能登录多个用户!\n"

else:

if self.userList.findUser(name)!= None: #用户列表中已存在该用户名

newStr = "不能重复登录!\n";

try: #发送内容???

self.server.sendto(newStr, self.addr, self.port)

except:

Exception, e

print (e)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值