python socket thread_python 使用socket与thread进行实时通信

本文编写于 226 天前,最后修改于 226 天前,其中某些信息可能已经过时。

前言

我又双叒叕好久不更新了,来记录下最近的学习成果叭,最近学习了Python的多线程和socket,然后突发奇想结合起来写了一个小玩意,这个小玩意呢可以实现实时通信,分别是通过一个服务端和多个客户端,客户端将消息发送到服务端,服务端再将消息转发给你想要发送给的那个人,并且支持一些指令如查看当前在线名单,查看某用户信息等。

效果

bilibili.gif

bilibili.gif

bilibili.gif

源码# Server.py

import socket

import threading

import json

serverAddress = ("0.0.0.0", 9000)

jsonDicts = {

'dictType': 0,

}

onlineList = []

userData = {}

threadDicts = {}

def jsonEncode(dicts):

return json.dumps(dicts).encode('utf-8')

def jsonDecode(dicts):

return json.loads(dicts.decode('utf-8'))

class DataBind:

def __init__(self, threadName):

self.threadName = threadName

def bind(self, dicts, connect, address):

onlineList.append(dicts["username"])

userData[dicts["username"]] = self.threadName

threadDicts[self.threadName] = {

'username': dicts["username"],

'phoneNumber': dicts["phoneNumber"],

'connect': connect,

'address': address,

'ip': address[0],

'port': address[1]

}

print("user " + dicts["username"] + " connect successful...")

print("user " + dicts["username"] + " data binding successful...")

return True

def unBind(self):

userInfo = threadDicts[self.threadName]

onlineList.pop(onlineList.index(userInfo["username"]))

userData.pop(userInfo["username"])

threadDicts.pop(self.threadName)

print("user " + userInfo["username"] + " disconnect...")

print("user " + userInfo["username"] + " data unbind successful...")

return True

class UserCommand:

def __init__(self):

...

def help(self, args):

str = """

---------- Command Help ----------

/getOnlineUser:/ls view online users...

/see [UserName] view user info...

/help view help...

---------- Help End ----------

"""

return str

def getOnlineUser(self, args):

return str(onlineList)

def ls(self, args):

return self.getOnlineUser(args)

def see(self, args):

arg = args.split(" ")

if arg[0] in onlineList:

userDict = threadDicts[userData[arg[0]]]

str = """

---------- User Info ----------

UserName: %s

UserPhone: %s

UserIP: %s

---------- Info End ----------

""" % (userDict["username"], userDict["phoneNumber"], userDict["ip"])

return str

else:

return "The user is not online..."

class SocketServer(socket.socket):

def __init__(self):

super(SocketServer, self).__init__()

def bind(self, address):

print("Binding address '" + str(address) + "'...")

super(SocketServer, self).bind(address)

def accept(self):

connect, address = super(SocketServer, self).accept()

print(str(address) + " connect this server...")

return connect, address

class SocketThread(threading.Thread):

def __init__(self, connect, address):

super(SocketThread, self).__init__()

self.connect = connect

self.address = address

def run(self):

while True:

dataBind = DataBind(self.getName())

try:

msg = jsonDecode(self.connect.recv(1024))

if msg["dictType"] == 0:

dataBind.bind(msg, self.connect, self.address)

jsonDicts["dictType"] = 1

jsonDicts["sender"] = "Server"

str = """

user data binding successful...

Input /help view help...

Input >[UserName] [Message] send message

"""

jsonDicts["message"] = str

self.connect.send(jsonEncode(jsonDicts))

elif msg["dictType"] == 1:

if msg["toUser"] in onlineList:

userDict = threadDicts[userData[msg["toUser"]]]

jsonDicts["dictType"] = 0

jsonDicts["sender"] = msg["username"]

jsonDicts["message"] = msg["message"]

userDict["connect"].send(jsonEncode(jsonDicts))

else:

jsonDicts["dictType"] = 1

jsonDicts["sender"] = "Server"

jsonDicts["message"] = "The user is not online..."

self.connect.send(jsonEncode(jsonDicts))

elif msg["dictType"] == 2:

if hasattr(UserCommand(), msg["userCommand"]):

command = getattr(UserCommand(), msg["userCommand"])

jsonDicts["dictType"] = 1

jsonDicts["sender"] = "Server"

jsonDicts["message"] = command(msg["userArgs"])

self.connect.send(jsonEncode(jsonDicts))

except socket.error as e:

dataBind.unBind()

return False

if __name__ == "__main__":

sock = SocketServer()

sock.bind(serverAddress)

sock.listen()

while True:

connect, address = sock.accept()

thread = SocketThread(connect, address)

thread.start()# Client.py

import socket

import threading

import json

connectAddress = ("127.0.0.1", 9000)

jsonDicts = {

'dictType': 0,

'username': 'ZeroY',

'phoneNumber': 17700000000

}

def jsonEncode(dicts):

return json.dumps(dicts).encode('utf-8')

def jsonDecode(dicts):

return json.loads(dicts.decode('utf-8'))

class SocketClient(socket.socket):

def __init__(self):

super(SocketClient, self).__init__()

def connect(self, address):

super(SocketClient, self).connect(address)

self.send(jsonDicts)

print("Connect to " + str(address))

def send(self, data: bytes, flags: int = ...):

super(SocketClient, self).send(jsonEncode(data))

class SocketThread(threading.Thread):

def __init__(self, sockets):

super(SocketThread, self).__init__()

self.sockets = sockets

def run(self):

while True:

userMessage = input("you command: ")

if userMessage.strip() == "": continue

if userMessage[0] == '>': # send info to user

jsonDicts["dictType"] = 1

commandArgs = userMessage.split(" ")

if '>' in commandArgs[0]:

jsonDicts["toUser"] = commandArgs[0].lstrip(">")

jsonDicts["message"] = userMessage.lstrip(commandArgs[0] + " ")

elif userMessage[0] == '/': # send command to server

jsonDicts["dictType"] = 2

commandArgs = userMessage.split(" ")

if '/' in commandArgs[0]:

jsonDicts["userCommand"] = commandArgs[0].lstrip("/")

jsonDicts["userArgs"] = userMessage.lstrip(commandArgs[0] + " ")

else:

continue

self.sockets.send(jsonDicts)

if __name__ == "__main__":

sock = SocketClient()

sock.connect(connectAddress)

thread = SocketThread(sock)

thread.start()

while True:

try:

msg = jsonDecode(sock.recv(1024))

print("\n" + msg["sender"] + " to you: " + msg["message"])

except socket.error as e:

print("The server closed connect...")

sock.close()

break

就是这个样子啦,有啥写的比较烂的地方欢迎大佬指正,初学者有啥不懂的也欢迎提问吖!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值