python socket 网络聊天室_基于python的socket和fork模块实现简易聊天室

基于python的socket和fork模块实现简易聊天室

服务器端

‘’’

名称:网络聊天室

环境:Python3.5

技术:socket fork

‘’’

import socket

import os

import sys

创建网络连接

def main():

# 创建UDP套接字

server = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

# 设置端口复用

server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

# 绑定地址

ADDRESS = (‘0.0.0.0’,8888)

server.bind(ADDRESS)

# 创建多进程,子进程负责管理员喊话,父进程和客户端交互

pid = os.fork()

if pid < 0:

# 一旦进程创建失败就结束

print('进程创建失败')

return

# 子进程负责管理员发送消息

elif pid == 0:

print('负责管理员喊话的进程')

# 父进程处理客户端的各种请求

else:

doRequest(server)

处理客户端请求的函数

def doRequest(server):

# 定义存储结构

user = {}

while True:

# 收消息

message,addr = server.recvfrom(1024)

# msgList : [‘L’,‘金毛狮王’]

msgList = message.decode().split(’ ')

if msgList[0] == ‘L’:

doLogin(server,user,msgList[1],addr)

elif msgList[0] == ‘C’:

# msgList: [‘C’,‘name’,‘你好’,‘步惊云’]

content = ’ '.join(msgList[2:])

# 发给其他所有成员

doChat(server,content,user,msgList[1])

elif msgList[0] == ‘Q’:

doQuit(server,msgList[1],user)

进入到聊天室请求处理函数

def doLogin(server,user,name,addr):

# {name:addr}

# 判断姓名是否存在

if (name in user) or name == ‘管理员’:

server.sendto(‘该用户已存在’.encode(),addr)

return

# 名字不存在,发送OK给客户端,允许进入

server.sendto(‘OK’.encode(),addr)

# 先通知其他人

message = ‘欢迎 %s 进入聊天室’ % name

for u in user:

server.sendto(message.encode(),user[u])

# 加入存储结构user中

user[name] = addr

聊天函数(把消息发给其他成员)

def doChat(server,content,user,name):

# 丰满消息

message = ‘%s说:%s’ % (name,content)

for u in user:

# 发给其他成员

if u != name:

server.sendto(message.encode(),user[u])

处理客户端退出函数

def doQuit(server,name,user):

# 通知其他成员

message = ‘%s 退出了聊天室’ % name

for u in user:

if u != name:

server.sendto(message.encode(),user[u])

# 给退出者本人发消息

else:

server.sendto(b’EXIT’,user[name])

# 从存储结构中删除

del user[name]

if name == “main”:

main()

客户端

import socket

import os

import sys

创建套接字函数

def main():

# 从命令行输入IP地址和端口号

if len(sys.argv) < 3:

print(‘参数错误’)

return

ADDRESS = (sys.argv[1],int(sys.argv[2]))

# 创建UDP套接字

client = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)

# 接收用户输入,包装后发给服务端

while True:

name = input(‘请输入姓名:’)

message = 'L ’ + name

# 向服务器发送消息

client.sendto(message.encode(),ADDRESS)

# 接收服务器反馈

data,addr = client.recvfrom(1024)

if data.decode() == ‘OK’:

print(‘您已进入聊天室’)

break

else:

# 打印不允许进入的原因

print(data.decode())

# 创建进程,子进程发消息,父进程收消息

pid = os.fork()

if pid < 0:

sys.exit('创建进程失败')

# 子进程发消息

elif pid == 0:

sendMsg(client,name,ADDRESS)

# 父进程收消息

else:

recvMsg(client)

子进程发消息函数

def sendMsg(client,name,ADDRESS):

# 发消息给服务端,服务端再进行转发

while True:

content = input(‘请发言(quit退出):’)

# 退出

if content == ‘quit’:

message = 'Q ’ + name

client.sendto(message.encode(),ADDRESS)

sys.exit(‘退出聊天室’)

# 包装消息

message = ‘C %s %s’ % (name,content)

client.sendto(message.encode(),ADDRESS)

父进程收消息函数

def recvMsg(client):

while True:

message,addr = client.recvfrom(1024)

# 父进程退出

if message.decode() == ‘EXIT’:

os._exit(0)

print(message.decode())

if name == ‘main’:

main()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值