js333 > 计算机互联网 > python编写简易聊天室实现局域网内聊天功能金沙

原标题:python编写简易聊天室实现局域网内聊天功能金沙

浏览次数:90 时间:2019-10-03

可以向局域网内开启接收信息功能的ip进行发送信息,我们可以写两段端口不同的代码来实现在一台电脑上与自己聊天.

具体思路,设置服务器监听端口,客户端接入时,列入数组,有消息进来,选择消息传播方式。这里设置boardcast 广播模式,消息循环发送到所有客户端,完成简易聊天功能。
下面开始完成客户端

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

from socket import *


def udp_send(udp_socket):
  # 发送消息 接收用户输入内容
  send_mes = input("请输入发送内容:")
  # 接收用户输入ip
  ip = input("请输入ip地址:")
  # 接收用户输入端口号
  port = int(input("请输入端口号"))
  # 发送消息 内容进行编码
  udp_socket.sendto(send_mes.encode("gbk"), (ip, port))


def udp_recvfrom(udp_socket):
  # 接收消息 最多4096个字节 
  get_mes, get_ip = udp_socket.recvfrom(4096)
  print("收到来自%s的消息:%s" % (str(get_ip), get_mes.decode("gbk")))


def main():
  # 创建套接字
  udp_socket = socket(AF_INET, SOCK_DGRAM)
  # 设置固定端口
  udp_socket.bind(("", 8889))

  while True:
    print("*" * 50)
    print("----------无敌聊天器----------")
    print("1.发送消息")
    print("2.接收消息")
    print("0.退出系统")
    print("*" * 50)

    user = input("请输入要执行的操作:")

    if user == "1":

      udp_send(udp_socket)

    elif user == "2":

      udp_recvfrom(udp_socket)

    elif user == "0":
      break

    else:

      print("输入有误")
  # 关闭套接字
  udp_socket.close()


if __name__ == "__main__":
  main()

思路,访问监听的端口号,输入用户名和消息,发送至服务端,服务端接受后,循环广播至每个客户端,实现聊天功能。

本文实例为大家分享了python实现简单聊天室的具体代码,供大家参考,具体内容如下

功能:

金沙js333娱乐场 1

import socket
import json

obj = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
obj.bind(('127.0.0.1', 12346))

conn_list = []
user_list = []

while True:
  try:
    receive_data, client_address = obj.recvfrom(1024)
    js = json.loads(receive_data.decode())
    # 登录消息
    if js['type'] == 'login':

      nickname = str(js['nickname'])
      if nickname in user_list:
        obj.sendto(json.dumps({'login': 'fail',
                    'errormessage': 'the nickname is exists'}).encode(),
              client_address)
      else:
        # 向其他用户发送通知
        for i in range(len(conn_list)):
          obj.sendto(json.dumps(
            {
              'type': 'message',
              'message': '[system]' + nickname + '已登录.'
            }).encode(), conn_list[i])
        user_list.append(nickname)
        conn_list.append(client_address)
        print(nickname, client_address, '登录成功!')
        obj.sendto(json.dumps({'login': 'success',
                    'nickname': nickname}).encode(), client_address)

    # 群发消息
    elif js['type'] == 'broadcast':
      message = js['message']
      nickname = js['nickname']
      for i in range(len(conn_list)):
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': nickname + ':' + message
          }).encode(), conn_list[i])

    # 私发消息
    elif js['type'] == 'sendto':
      who = js['who']
      nickname = js['nickname']
      message = js['message']
      # 检查用户是否存在
      if who not in user_list:
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': who + ' not exist or not online.please try later.'
          }).encode(),
          client_address)
      else:
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': nickname + ' whisper to you: ' + message
          }).encode(),
          conn_list[user_list.index(who)])

    # 查看用户列表
    elif js['type'] == 'catusers':
      users = json.dumps(user_list)
      obj.sendto(json.dumps(
        {
          'type': 'message',
          'message': users,
        }).encode(),
        client_address)

    # 查看用户IP
    elif js['type'] == 'catip':
      who = js['who']
      if who not in user_list:
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': who + ' not exist or not online.please try later.'
          }).encode(),
          client_address)
      else:
        addr = json.dumps(conn_list[user_list.index(who)])
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': addr,
          }).encode(),
          client_address)

    # 离线消息
    elif js['type'] == 'offline':
      user_list.remove(js['nickname'])
      conn_list.remove(client_address)
      obj.sendto(
        (js['nickname'] + 'offline.').encode(),
        client_address)
      # 向其他用户发送通知
      for i in range(len(conn_list)):
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': '[system]' + nickname + '下线了.'
          }).encode(), conn_list[i])

    # 发送文件请求
    elif js['type'] == 'filequest':
      who = js['who']
      if who not in user_list:
        obj.sendto(json.dumps(
          {
            'type': 'message',
            'message': who + ' not exist or not online.please try later.'
          }).encode(),
          client_address)
      else:
        js['send_ip'] = client_address[0]
        js['send_port'] = client_address[1]
        obj.sendto(json.dumps(js).encode(),
              conn_list[user_list.index(who)])
        print(js['nickname'], 'request to send file to', who)

    # 发送文件请求回复
    elif js['type'] == 'fileres':
      who = js['who']
      if js['fileres'] == 'yes':
        js['recv_ip'] = client_address[0]
        js['recv_port'] = client_address[1]
        print(js['nickname'], 'agree to receive file from', js['who'])
      else:
        print(js['nickname'], 'deny to receive file from', js['who'])
      obj.sendto(json.dumps(js).encode(),
            conn_list[user_list.index(who)])

  except Exception as e:
    print(e)

关键点:

// 创建于服务端的连接
varserver = net.connect({ port:2080, host:'/*你机器的端口*/'}, () => {
console.log(`Welcome${name}to 2080 chatroom`);
// 监听服务端发过来的数据
server.on('data', (chunk) => {
try{
var signal = JSON.parse(chunk.toString().trim());
var procotol = signal.procotol;
switch(procotol) {
case'boardcast':
//广播模式接受数据。
console.log('nboardcast');
console.log(signal.from +'>');
console.log(signal.message);
//收到聊天内容打印出来
rl.prompt();
break;
default:
server.write('中午吃啥');
break;
}
}catch(error) {
server.write('弄啥咧!');
}
});
rl.setPrompt(name +'> ');
rl.prompt();
rl.on('line', (line) => {
var send = {
procotol:'boardcast',
from: name,
message: line.toString().trim()
};
server.write(JSON.stringify(send));
rl.prompt();
}).on('close', () => {
});
});
});

实现了群发、私发、点对点文件互传功能。

本文实例为大家分享了python实现局域网内聊天功能的具体代码,供大家参考,具体内容如下

试想一下,上机课,你和你心爱的姑娘坐了好远好远,三个小时的寂寞,谁能懂,在机房,或信号差,或老师管的严,不让玩手机。
又试想一下,上机课,你想在你心爱的姑娘面前表现出一副大牛的样子,这样,之后课设,作业,她便会不自居的向你靠来,成为人赢,就在现在。
这篇文章教大家做一个局域网的简易聊天室,一百行代码,实现你的装哔~梦。
前期准备,部署 node 环境。
为什么要用NODE?它足够小,比JAVA /C++ 部署方便得多,JS够简单,记事本就能写出你华丽的代码。废话不多说,开始。
用到API,node.net.
//首先建立服务端

您可能感兴趣的文章:

  • python编写简易聊天室实现局域网内聊天功能
  • Python Socket编程之多线程聊天室
  • Python实现基于C/S架构的聊天室功能详解
  • Python聊天室程序(基础版)
  • Python socket实现简单聊天室
  • python基于twisted框架编写简单聊天室
  • 小小聊天室Python代码实现
  • python socket多线程通讯实例分析(聊天室)
  • Python聊天室实例程序分享
  • 金沙js333娱乐场 ,基于进程内通讯的python聊天室实现方法
  • Python实现的使用telnet登陆聊天室实例
  • Python socket C/S结构的聊天室应用实现
  • python实现多人聊天室

要想实现此功能必须将程序的端口固定

学弟学妹们,你们下学期的课设,有一项加分项就是实现聊天功能,代码放到这里咯。不懂随时来问。

客户端代码如下:

constnet = require('net');
// 用于存储所有的连接
var clients = [];
var port =2080; //定义服务器端口
server.listen(port, (err) => {
if(err) {
console.log('端口被占用');
return false;
}
console.log(`服务端正常启动监听【${port}】端口`);
})
varserver = net.createServer((socket) => {
clients.push(socket);
console.log(`Welcome${socket.remoteAddress}to ${port} chatroom`);
functionboardcast(signal) {
console.log(signal);
// 肯定有用户名和消息
var username = signal.from;
var message = signal.message;
// 我们要发给客户端的东西
var send = {
procotol: signal.procotol,
from: username,
message: message
};
// 广播消息
clients.forEach(client=> {
client.write(JSON.stringify(send));
});
}
// 有任何客户端发消息都会触发
socket.on('data', (chunk) => {
try{
var signal = JSON.parse(chunk.toString().trim());
var procotol = signal.procotol;
switch(procotol) {
case'boardcast':
boardcast(signal);
break;
default:
socket.write('啥,你想吃日新楼?');
break;
}
}catch(error) {
socket.write('弄啥咧!');
}
});
});

该程序由客户端与服务器构成,使用UDP服务,服务器端绑定本地IP和端口,客户端由系统随机选择端口。

使用json模块进行消息的封装序列化,在接收方进行解析。

import socket
import threading
import json
import os
from cmd import Cmd


class Client(Cmd):
  """
  客户端
  """
  prompt = '>>>'
  intro = '[Welcome] 简易聊天室客户端(Cli版)n' + '[Welcome] 输入help来获取帮助n'
  buffersize = 1024

  def __init__(self, host):
    """
    构造
    """
    super().__init__()
    self.__socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    # self.__id = None
    self.__nickname = None
    self.__host = host
    self.thread_recv = None
    self.threadisalive = False
    # 是否在接收文件
    self.recvfile = False
    # 是否在发送文件
    self.sendfile = False
    self.filesize = None
    self.sendfilesize = None

    # 接收文件包计数
    self.filecount = None
    # 接收文件名
    self.filename = None
    # 发送文件名
    self.sendfilename = None

    # 发送者
    self.filefrom = None
    # 接收者
    self.fileto = None

    # 接收文件流
    self.file_recv = None
    # 发送文件流
    self.file_send = None

    # 接收文件地址
    self.filefrom_addr = None
    # 发送文件地址
    self.fileto_addr = None

  def __receive_message_thread(self):
    """
    接受消息线程
    """
    while self.threadisalive:
      # noinspection PyBroadException
      try:
        buffer, addr = self.__socket.recvfrom(1024)
        '''
        文件流由发送端直接发送,不经过服务器,故当发送端发来的消息时,将收到的数据存入文件
        '''
        if (addr != self.__host) & (addr == self.filefrom_addr) & self.recvfile:
          self.file_recv.write(buffer)
          self.filecount += 1
          if self.filecount * 1024 >= self.filesize:
            self.file_recv.close()
            print(self.filename, 'is received.')
            self.recvfile = False
          continue

        js = json.loads(buffer.decode())

        # 若接收的数据为消息信息,则显示
        if js['type'] == 'message':
          print(js['message'])

        # 若接收的数据为文件发送请求,则存储文件信息,并显示
        elif js['type'] == 'filequest':
          if self.recvfile:
            self.__socket.sendto(json.dumps({
              'type': 'fileres',
              'fileres': 'no',
              'nickname': self.__nickname,
              'who': js['nickname'],
              'errormessage': 'is transfroming files.',
            }).encode(), self.__host)
            continue
          filename = js['filename']
          who = js['nickname']
          filesize = js['filesize']
          self.recvfile = True
          self.filesize = filesize
          self.filename = filename
          self.filecount = 0
          self.filefrom = who
          self.filefrom_addr = (js['send_ip'], js['send_port'])

          print('[system]:', who, ' send a file(',
             filename, ') to you. receive? ')

        # 接受的数据为请求回复,若同意接收则存储服务器发来的接收方的地址,并开启发送线程
        elif js['type'] == 'fileres':
          if js['fileres'] == 'yes':
            print(js['recv_ip'], js['recv_port'])
            self.fileto_addr = (js['recv_ip'], js['recv_port'])
            thread = threading.Thread(
              target=self.__send_file_thread)
            thread.start()
          else:
            print(js['nickname'], js['errormessage'])
            self.sendfile = False

      except Exception as e:
        print(e)
        print('[Client] 无法从服务器获取数据')

  def __send_broadcast_message_thread(self, message):
    """
    发送广播消息线程
    :param message: 消息内容
    """
    self.__socket.sendto(json.dumps({
      'type': 'broadcast',
      'nickname': self.__nickname,
      'message': message,
    }).encode(), self.__host)

  def __send_file_thread(self):
    """
    发送文件线程
    :param message: 消息内容
    """
    filecount = 0
    print('[system]', 'sending the file...')
    while filecount * 1024 <= self.sendfilesize:
      self.__socket.sendto(
        self.file_send.read(1024), self.fileto_addr)
      filecount += 1
    self.file_send.close()
    self.sendfile = False
    print('[system]', 'the file is sended.')

  def __send_whisper_message_thread(self, who, message):
    """
    发送私发消息线程
    :param message: 消息内容
    """
    self.__socket.sendto(json.dumps({
      'type': 'sendto',
      'who': who,
      'nickname': self.__nickname,
      'message': message
    }).encode(), self.__host)

  def send_exit(self):
    self.__socket.sendto(json.dumps({
      'type': 'offline',
      'nickname': self.__nickname,
    }).encode(), self.__host)


  def start(self):
    """
    启动客户端
    """
    self.cmdloop()

  def do_login(self, args):
    """
    登录聊天室
    :param args: 参数
    """
    nickname = args.split(' ')[0]

    # 将昵称发送给服务器,获取用户id
    self.__socket.sendto(json.dumps({
      'type': 'login',
      'nickname': nickname,
    }).encode(), self.__host)
    # 尝试接受数据

    buffer = self.__socket.recvfrom(1300)[0].decode()
    obj = json.loads(buffer)
    if obj['login'] == 'success':
      self.__nickname = nickname
      print('[Client] 成功登录到聊天室')
      self.threadisalive = True
      # 开启子线程用于接受数据
      self.thread_recv = threading.Thread(
        target=self.__receive_message_thread)
      self.thread_recv.setDaemon(True)
      self.thread_recv.start()
    else:
      print('[Client] 无法登录到聊天室', obj['errormessage'])

  def do_send(self, args):
    """
    发送消息
    :param args: 参数
    """
    if self.__nickname is None:
      print('请先登录!login nickname')
      return
    message = args
    # 开启子线程用于发送数据
    thread = threading.Thread(
      target=self.__send_broadcast_message_thread, args=(message, ))
    thread.setDaemon(True)
    thread.start()

  def do_sendto(self, args):
    """
    发送私发消息
    :param args: 参数
    """
    if self.__nickname is None:
      print('请先登录!login nickname')
      return
    who = args.split(' ')[0]
    message = args.split(' ')[1]
    # # 显示自己发送的消息
    # print('[' + str(self.__nickname) + '(' + str(self.__id) + ')' + ']', message)
    # 开启子线程用于发送数据
    thread = threading.Thread(
      target=self.__send_whisper_message_thread, args=(who, message))
    thread.setDaemon(True)
    thread.start()

  def do_catusers(self, arg):
    if self.__nickname is None:
      print('请先登录!login nickname')
      return
    catmessage = json.dumps({'type': 'catusers'})
    self.__socket.sendto(catmessage.encode(), self.__host)

  def do_catip(self, args):
    if self.__nickname is None:
      print('请先登录!login nickname')
      return
    who = args
    catipmessage = json.dumps({'type': 'catip', 'who': who})
    self.__socket.sendto(catipmessage.encode(), self.__host)

  def do_help(self, arg):
    """
    帮助
    :param arg: 参数
    """
    command = arg.split(' ')[0]
    if command == '':
      print('[Help] login nickname - 登录到聊天室,nickname是你选择的昵称')
      print('[Help] send message - 发送消息,message是你输入的消息')
      print('[Help] sendto who message - 私发消息,who是用户名,message是你输入的消息')
      print('[Help] catusers - 查看所有用户')
      print('[Help] catip who - 查看用户IP,who为用户名')
      print('[Help] sendfile who filedir - 向某用户发送文件,who为用户名,filedir为文件路径')
      print('[Help] getfile filename who yes/no - 接收文件,filename 为文件名,who为发送者,yes/no为是否接收')
    elif command == 'login':
      print('[Help] login nickname - 登录到聊天室,nickname是你选择的昵称')
    elif command == 'send':
      print('[Help] send message - 发送消息,message是你输入的消息')
    elif command == 'sendto':
      print('[Help] sendto who message - 发送私发消息,message是你输入的消息')
    else:
      print('[Help] 没有查询到你想要了解的指令')

  def do_exit(self, arg): # 以do_*开头为命令
    print("Exit")
    self.send_exit()
    try:
      self.threadisalive = False
      self.thread_recv.join()
    except Exception as e:
      print(e)
    # self.__socket.close()

  def do_sendfile(self, args):
    who = args.split(' ')[0]
    filepath = args.split(' ')[1]
    filename = filepath.split('\')[-1]
    # 判断是否在发送文件
    if self.sendfile:
      print('you are sending files, please try later.')
      return
    if not os.path.exists(filepath):
      print('the file is not exist.')
      return
    filesize = os.path.getsize(filepath)
    # print(who, filename, filesize)

    self.sendfile = True
    self.fileto = who
    self.sendfilename = filename
    self.sendfilesize = filesize
    self.file_send = open(filepath, 'rb')

    self.__socket.sendto(json.dumps({
      'type': 'filequest',
      'nickname': self.__nickname,
      'filename': self.sendfilename,
      'filesize': self.sendfilesize,
      'who': self.fileto,
      'send_ip': '',
      'send_port': '',
    }).encode(), self.__host)

    print('request send...')

    # fileres = self.__socket.recvfrom(1024)[0].decode()
    # js = json.loads(fileres)

  def do_getfile(self, args):
    filename = args.split(' ')[0]
    who = args.split(' ')[1]
    ch = args.split(' ')[2]
    # print(self.filename is not None, filename, self.filename, who, self.filefrom)
    if (self.filename is not None) & (filename == self.filename) & (who == self.filefrom):
      if ch == 'yes':
        self.file_recv = open(self.filename, 'wb')
        self.__socket.sendto(json.dumps({
          'type': 'fileres',
          'fileres': 'yes',
          'nickname': self.__nickname,
          'who': who,
          'recv_ip': '',
          'recv_port': '',
        }).encode(), self.__host)
        print('you agree to reveive the file(', filename, ') from', who)

      else:
        self.__socket.sendto(json.dumps({
          'type': 'fileres',
          'fileres': 'no',
          'nickname': self.__nickname,
          'errormessage': 'deny the file.',
          'who': who,
          'recv_ip': '',
          'recv_port': '',
        }).encode(), self.__host)
        print('you deny to reveive the file(', filename, ') from', who)
        self.recvfile = False
    else:
      print('the name or sender of the file is wrong.')


c = Client(('127.0.0.1', 12346))
c.start()

服务器端主要进行消息的分类转发处理,用户列表、地址列表的维护。

客户端自建了一个类继承了Cmd模块,使用自定义的命令command进行操作,调用相应的do_command方法。

刚刚接触python编程,又从接触java开始一直对socket模块感兴趣,所以就做了一个聊天室的小程序。

服务器端代码如下:

本文由js333发布于计算机互联网,转载请注明出处:python编写简易聊天室实现局域网内聊天功能金沙

关键词:

上一篇:解决方法,thinkphp做文字水印

下一篇:没有了