当前位置:首页 > 代码 > 正文

聊天室系统代码的简单介绍

admin 发布:2022-12-19 21:30 93


今天给各位分享聊天室系统代码的知识,其中也会对进行解释,如果能碰巧解决你现在面临的问题,别忘了关注本站,现在开始吧!

本文目录一览:

如何用Python编写一个聊天室

一、课程介绍

1.简介

本次项目课是实现简单聊天室程序的服务器端和客户端。

2.知识点

服务器端涉及到asyncore、asynchat和socket这几个模块,客户端用到了telnetlib、wx、time和thread这几个模块。

3.所需环境

本次课中编写客户端需要用到wxPython,它是一个GUI工具包,请先使用下面的命令安装:

$ sudo apt-get install python-wxtools

密码为shiyanlou

4.项目效果截图

登录窗口

聊天窗口

二、项目实战(服务器端)

1.服务器类

首先需要一个聊天服务器,这里继承asyncore的dispatcher类来实现,代码如下

class ChatServer(dispatcher):

"""

聊天服务器

"""

def __init__(self, port):

dispatcher.__init__(self)

self.create_socket(socket.AF_INET, socket.SOCK_STREAM)

self.set_reuse_addr()

self.bind(('', port))

self.listen(5)

self.users = {}

self.main_room = ChatRoom(self)

def handle_accept(self):

conn, addr = self.accept()

ChatSession(self, conn)

2.会话类

有了服务器类还需要能维护每个用户的连接会话,这里继承asynchat的async_chat类来实现,代码如下:

class ChatSession(async_chat):

"""

负责和单用户通信

"""

def __init__(self, server, sock):

async_chat.__init__(self, sock)

self.server = server

self.set_terminator('\n')

self.data = []

self.name = None

self.enter(LoginRoom(server))

def enter(self, room):

'从当前房间移除自身,然后添加到指定房间'

try:

cur = self.room

except AttributeError:

pass

else:

cur.remove(self)

self.room = room

room.add(self)

def collect_incoming_data(self, data):

'接受客户端的数据'

self.data.append(data)

def found_terminator(self):

'当客户端的一条数据结束时的处理'

line = ''.join(self.data)

self.data = []

try:

self.room.handle(self, line)

except EndSession:

self.handle_close()

def handle_close(self):

async_chat.handle_close(self)

self.enter(LogoutRoom(self.server))

3.命令解释器

现在就需要一个命令解释器能够解释用户的命令,例如登录、查询在线用户和发消息等,代码如下:

class CommandHandler:

"""

命令处理类

"""

def unknown(self, session, cmd):

'响应未知命令'

session.push('Unknown command: %s\n' % cmd)

def handle(self, session, line):

'命令处理'

if not line.strip():

return

parts = line.split(' ', 1)

cmd = parts[0]

try:

line = parts[1].strip()

except IndexError:

line = ''

meth = getattr(self, 'do_' + cmd, None)

try:

meth(session, line)

except TypeError:

self.unknown(session, cmd)

4.房间

接下来就需要实现聊天室的房间了,这里我们定义了三种房间,分别是用户刚登录时的房间、聊天的房间和退出登录的房间,这三种房间都有一个公共的父类,代码如下:

class Room(CommandHandler):

"""

包含多个用户的环境,负责基本的命令处理和广播

"""

def __init__(self, server):

self.server = server

self.sessions = []

def add(self, session):

'一个用户进入房间'

self.sessions.append(session)

def remove(self, session):

'一个用户离开房间'

self.sessions.remove(session)

def broadcast(self, line):

'向所有的用户发送指定消息'

for session in self.sessions:

session.push(line)

def do_logout(self, session, line):

'退出房间'

raise EndSession

class LoginRoom(Room):

"""

刚登录的用户的房间

"""

def add(self, session):

'用户连接成功的回应'

Room.add(self, session)

session.push('Connect Success')

def do_login(self, session, line):

'登录命令处理'

name = line.strip()

if not name:

session.push('UserName Empty')

elif name in self.server.users:

session.push('UserName Exist')

else:

session.name = name

session.enter(self.server.main_room)

class ChatRoom(Room):

"""

聊天用的房间

"""

def add(self, session):

'广播新用户进入'

session.push('Login Success')

self.broadcast(session.name + ' has entered the room.\n')

self.server.users[session.name] = session

Room.add(self, session)

def remove(self, session):

'广播用户离开'

Room.remove(self, session)

self.broadcast(session.name + ' has left the room.\n')

def do_say(self, session, line):

'客户端发送消息'

self.broadcast(session.name + ': ' + line + '\n')

def do_look(self, session, line):

'查看在线用户'

session.push('Online Users:\n')

for other in self.sessions:

session.push(other.name + '\n')

class LogoutRoom(Room):

"""

用户退出时的房间

"""

def add(self, session):

'从服务器中移除'

try:

del self.server.users[session.name]

except KeyError:

pass

5.服务器端完整代码

#!/usr/bin/python

# encoding: utf-8

from asyncore import dispatcher

from asynchat import async_chat

import socket, asyncore

PORT = 6666 #端口

class EndSession(Exception):

"""

自定义会话结束时的异常

"""

pass

class CommandHandler:

"""

命令处理类

"""

def unknown(self, session, cmd):

'响应未知命令'

session.push('Unknown command: %s\n' % cmd)

def handle(self, session, line):

'命令处理'

if not line.strip():

return

parts = line.split(' ', 1)

cmd = parts[0]

try:

line = parts[1].strip()

except IndexError:

line = ''

meth = getattr(self, 'do_' + cmd, None)

try:

meth(session, line)

except TypeError:

self.unknown(session, cmd)

class Room(CommandHandler):

"""

包含多个用户的环境,负责基本的命令处理和广播

"""

def __init__(self, server):

self.server = server

self.sessions = []

def add(self, session):

'一个用户进入房间'

self.sessions.append(session)

def remove(self, session):

'一个用户离开房间'

self.sessions.remove(session)

def broadcast(self, line):

'向所有的用户发送指定消息'

for session in self.sessions:

session.push(line)

def do_logout(self, session, line):

'退出房间'

raise EndSession

class LoginRoom(Room):

"""

刚登录的用户的房间

"""

def add(self, session):

'用户连接成功的回应'

Room.add(self, session)

session.push('Connect Success')

def do_login(self, session, line):

'登录命令处理'

name = line.strip()

if not name:

session.push('UserName Empty')

elif name in self.server.users:

session.push('UserName Exist')

else:

session.name = name

session.enter(self.server.main_room)

class ChatRoom(Room):

"""

聊天用的房间

"""

def add(self, session):

'广播新用户进入'

session.push('Login Success')

self.broadcast(session.name + ' has entered the room.\n')

self.server.users[session.name] = session

Room.add(self, session)

def remove(self, session):

'广播用户离开'

Room.remove(self, session)

self.broadcast(session.name + ' has left the room.\n')

def do_say(self, session, line):

'客户端发送消息'

self.broadcast(session.name + ': ' + line + '\n')

def do_look(self, session, line):

'查看在线用户'

session.push('Online Users:\n')

for other in self.sessions:

session.push(other.name + '\n')

class LogoutRoom(Room):

"""

用户退出时的房间

"""

def add(self, session):

'从服务器中移除'

try:

del self.server.users[session.name]

except KeyError:

pass

class ChatSession(async_chat):

"""

负责和单用户通信

"""

def __init__(self, server, sock):

async_chat.__init__(self, sock)

self.server = server

self.set_terminator('\n')

self.data = []

self.name = None

self.enter(LoginRoom(server))

def enter(self, room):

'从当前房间移除自身,然后添加到指定房间'

try:

cur = self.room

except AttributeError:

pass

else:

cur.remove(self)

self.room = room

room.add(self)

def collect_incoming_data(self, data):

'接受客户端的数据'

self.data.append(data)

def found_terminator(self):

'当客户端的一条数据结束时的处理'

line = ''.join(self.data)

self.data = []

try:

self.room.handle(self, line)

except EndSession:

self.handle_close()

def handle_close(self):

async_chat.handle_close(self)

self.enter(LogoutRoom(self.server))

class ChatServer(dispatcher):

"""

聊天服务器

"""

def __init__(self, port):

dispatcher.__init__(self)

self.create_socket(socket.AF_INET, socket.SOCK_STREAM)

self.set_reuse_addr()

self.bind(('', port))

self.listen(5)

self.users = {}

self.main_room = ChatRoom(self)

def handle_accept(self):

conn, addr = self.accept()

ChatSession(self, conn)

if __name__ == '__main__':

s = ChatServer(PORT)

try:

asyncore.loop()

except KeyboardInterrupt:

print

三、项目实战(客户端)

完成了服务器端后,就需要实现客户端了,这里客户端连接服务器使用了telnetlib模块。

1.登录窗口

这里的图形界面包选择了wxPython,前面有安装说明,登录窗口通过继承wx.Frame类来实现,代码如下:

class LoginFrame(wx.Frame):

"""

登录窗口

速求用JAVA语言写聊天室的源代码

【ClientSocketDemo.java 客户端Java源代码】

import java.net.*;

import java.io.*;

public class ClientSocketDemo

{

//声明客户端Socket对象socket

Socket socket = null;

//声明客户器端数据输入输出流

DataInputStream in;

DataOutputStream out;

//声明字符串数组对象response,用于存储从服务器接收到的信息

String response[];

//执行过程中,没有参数时的构造方法,本地服务器在本地,取默认端口10745

public ClientSocketDemo()

{

try

{

//创建客户端socket,服务器地址取本地,端口号为10745

socket = new Socket("localhost",10745);

//创建客户端数据输入输出流,用于对服务器端发送或接收数据

in = new DataInputStream(socket.getInputStream());

out = new DataOutputStream(socket.getOutputStream());

//获取客户端地址及端口号

String ip = String.valueOf(socket.getLocalAddress());

String port = String.valueOf(socket.getLocalPort());

//向服务器发送数据

out.writeUTF("Hello Server.This connection is from client.");

out.writeUTF(ip);

out.writeUTF(port);

//从服务器接收数据

response = new String[3];

for (int i = 0; i response.length; i++)

{

response[i] = in.readUTF();

System.out.println(response[i]);

}

}

catch(UnknownHostException e){e.printStackTrace();}

catch(IOException e){e.printStackTrace();}

}

//执行过程中,有一个参数时的构造方法,参数指定服务器地址,取默认端口10745

public ClientSocketDemo(String hostname)

{

try

{

//创建客户端socket,hostname参数指定服务器地址,端口号为10745

socket = new Socket(hostname,10745);

in = new DataInputStream(socket.getInputStream());

out = new DataOutputStream(socket.getOutputStream());

String ip = String.valueOf(socket.getLocalAddress());

String port = String.valueOf(socket.getLocalPort());

out.writeUTF("Hello Server.This connection is from client.");

out.writeUTF(ip);

out.writeUTF(port);

response = new String[3];

for (int i = 0; i response.length; i++)

{

response[i] = in.readUTF();

System.out.println(response[i]);

}

}

catch(UnknownHostException e){e.printStackTrace();}

catch(IOException e){e.printStackTrace();}

}

//执行过程中,有两个个参数时的构造方法,第一个参数hostname指定服务器地址

//第一个参数serverPort指定服务器端口号

public ClientSocketDemo(String hostname,String serverPort)

{

try

{

socket = new Socket(hostname,Integer.parseInt(serverPort));

in = new DataInputStream(socket.getInputStream());

out = new DataOutputStream(socket.getOutputStream());

String ip = String.valueOf(socket.getLocalAddress());

String port = String.valueOf(socket.getLocalPort());

out.writeUTF("Hello Server.This connection is from client.");

out.writeUTF(ip);

out.writeUTF(port);

response = new String[3];

for (int i = 0; i response.length; i++)

{

response[i] = in.readUTF();

System.out.println(response[i]);

}

}

catch(UnknownHostException e){e.printStackTrace();}

catch(IOException e){e.printStackTrace();}

}

public static void main(String[] args)

{

String comd[] = args;

if(comd.length == 0)

{

System.out.println("Use localhost(127.0.0.1) and default port");

ClientSocketDemo demo = new ClientSocketDemo();

}

else if(comd.length == 1)

{

System.out.println("Use default port");

ClientSocketDemo demo = new ClientSocketDemo(args[0]);

}

else if(comd.length == 2)

{

System.out.println("Hostname and port are named by user");

ClientSocketDemo demo = new ClientSocketDemo(args[0],args[1]);

}

else System.out.println("ERROR");

}

}

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

【ServerSocketDemo.java 服务器端Java源代码】

import java.net.*;

import java.io.*;

public class ServerSocketDemo

{

//声明ServerSocket类对象

ServerSocket serverSocket;

//声明并初始化服务器端监听端口号常量

public static final int PORT = 10745;

//声明服务器端数据输入输出流

DataInputStream in;

DataOutputStream out;

//声明InetAddress类对象ip,用于获取服务器地址及端口号等信息

InetAddress ip = null;

//声明字符串数组对象request,用于存储从客户端发送来的信息

String request[];

public ServerSocketDemo()

{

request = new String[3]; //初始化字符串数组

try

{

//获取本地服务器地址信息

ip = InetAddress.getLocalHost();

//以PORT为服务端口号,创建serverSocket对象以监听该端口上的连接

serverSocket = new ServerSocket(PORT);

//创建Socket类的对象socket,用于保存连接到服务器的客户端socket对象

Socket socket = serverSocket.accept();

System.out.println("This is server:"+String.valueOf(ip)+PORT);

//创建服务器端数据输入输出流,用于对客户端接收或发送数据

in = new DataInputStream(socket.getInputStream());

out = new DataOutputStream(socket.getOutputStream());

//接收客户端发送来的数据信息,并显示

request[0] = in.readUTF();

request[1] = in.readUTF();

request[2] = in.readUTF();

System.out.println("Received messages form client is:");

System.out.println(request[0]);

System.out.println(request[1]);

System.out.println(request[2]);

//向客户端发送数据

out.writeUTF("Hello client!");

out.writeUTF("Your ip is:"+request[1]);

out.writeUTF("Your port is:"+request[2]);

}

catch(IOException e){e.printStackTrace();}

}

public static void main(String[] args)

{

ServerSocketDemo demo = new ServerSocketDemo();

}

}

如何用C语言编写一个简单的聊天室程序

这样:

#include stdlib.h

#include stdio.h

#include errno.h

#include string.h

#include unistd.h

#include netdb.h

#include sys/socket.h

#include netinet/in.h

#include sys/types.h

#include arpa/inet.h

#include pthread.h

#define MAXLINE 100;

void *threadsend(void *vargp);

void *threadrecv(void *vargp);

int main()

{

int *clientfdp;

clientfdp = (int *)malloc(sizeof(int));

*clientfdp = socket(AF_INET,SOCK_STREAM,0);

struct sockaddr_in serveraddr;

struct hostent *hp;

bzero((char *)serveraddr,sizeof(serveraddr));

serveraddr.sin_family = AF_INET;

serveraddr.sin_port = htons(15636);

serveraddr.sin_addr.s_addr = inet_addr("127.0.0.1");

if(connect(*clientfdp,(struct sockaddr *)serveraddr,sizeof(serveraddr)) 0){

      printf("connect error\n");

      exit(1);

}

pthread_t tid1,tid2;

printf("connected\n");

while(1){

pthread_create(tid1,NULL,threadsend,clientfdp);

pthread_create(tid2,NULL,threadrecv,clientfdp);

}

return EXIT_SUCCESS;

}

void *threadsend(void * vargp)

{

//pthread_t tid2;

int connfd = *((int *)vargp);

int idata;

char temp[100];

while(1){

//printf("me: \n ");

fgets(temp,100,stdin);

send(connfd,temp,100,0);

printf("          client send OK\n");

}

printf("client send\n");

return NULL;

}

void *threadrecv(void *vargp)

{

char temp[100];

int connfd = *((int *)vargp);

while(1){

int idata = 0;

idata = recv(connfd,temp,100,0);

if(idata 0){

printf("server :\n%s\n",temp);

}

}

return NULL;

}

扩展资料:

注意事项

linux下编译多线程代码时,shell提示找不到 pthread_create函数,原因是 pthread.h不是linux系统默认加载的库文件,应该使用类似如下gcc命令进行编译:

gcc echoserver.c -lpthread -o echoserver

只要注意 -lpthread参数就可以了。

聊天室系统代码的介绍就聊到这里吧,感谢你花时间阅读本站内容,更多关于、聊天室系统代码的信息别忘了在本站进行查找喔。

版权说明:如非注明,本站文章均为 AH站长 原创,转载请注明出处和附带本文链接;

本文地址:http://ahzz.com.cn/post/25163.html


取消回复欢迎 发表评论:

分享到

温馨提示

下载成功了么?或者链接失效了?

联系我们反馈

立即下载