`
CaptainCook
  • 浏览: 136963 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

简单多人聊天室的服务器端开发总结

    博客分类:
  • J2EE
阅读更多

服务器的根本创建方法是  创建一个ServerSocket的对象,让对象在某个端口上监听。
调用accept方法阻塞端口,如果有客户机连接上了服务器的该端口,然后启动一个新的socket与该客户机进行通信。
如果把通信的处理方法放在一个线程类里面,就可以实现多人同时访问,即多线程处理。

服务器的多线程处理类(多人聊天室)


从宏观上来看,服务器主要是做两件事情:
1、从客户端得到输入的内容;
2、将输入的内容接收后写到其他的客户端。

从这里就可以明白,服务器处理方法所需要的方法或者属性变量如下:

需要一个存放连接对象的列表,并提供对列表中连接对象的增加和删除操作。(存放线程列表,里面的线程是用来操作连接对象socket的)

需要一个获取客户端输入的方法,该方法通过客户端的readLine方法返回一个字符串,然后服务器将以流的形式,写到每一个客户端中

需要一个将某个客户端发过来的消息转发全部客户端的一个方法。遍历每个元素,然后写给客户端。

  处理类的本质其实是一个实现了多线程功能的 socket对象的包装类,在这个包装类中,所有的socket对象都可以从中获取到读写流对象,并且有读写方法,这样以来,服务器就不要担心如何去处理每个连接,它要做的只是将每个请求回应,然后将请求转交给处理类,即线程去处理。
其实可以说整个服务器的处理核心就是这个处理类,这个类的处理流程如下:
当创建了一个连接socket对象的线程之后,就将这个线程对象放入列表当中去,列表是静态的,所以可以让各个线程同时访问,或者说可以让各个线程共享这个变量。
之后就是将欢迎辞,发到各个线程所对应的socket对象,因为每个对象都在处理类中被包装了,所有的对象都有自己的读写流,则可以在每个单独的线程中去写信息。实现聊天室的效果。线程一直在等待读取客户端输入的数据,只要有输入,就会马上将数据反应到每个客户端上来。
如果输入某个字符,比如说“bye”就让其自动退出,将该线程多对应的连接对象close,将列表中该线程移除。

 总体来说,服务器端的开发流程和要注意的地方已经介绍完了,最重要的一点就是,服务器其实只是在等待,处理线程类才是最终的“劳动者”。了解和熟悉服务器的工作流程对以后客户端课服务器的同时开发有着不可或缺的作用。

 

服务器启动程序 写道

 

package cn.netjava.C_S.v3;

import java.net.ServerSocket;

public class ChatServerV3 {


//程序入口
public static void main(String[] args) {
ChatServerV3 ms=new ChatServerV3();
int port =9999;
ms.setUpServer(port);
}
//在指定端口上启动服务器
public void setUpServer(int port){
try{

ServerSocket sc=new ServerSocket(port);//在指定端口上构造一个服务器对象
new ChatTools().serverUI();
ChatTools.information.setText("简单聊天服务器创建成功,等待在端口: "+port+"\n");
while(true){//让服务器进入循环监听状态
java.net.Socket client=sc.accept();
ChatThread ct=new ChatThread(client);
ct.start();//启动一个线程,去处理这个客户机的连结对象
}
}catch(Exception ef){
ef.printStackTrace();
}
}
}

 

工具类代码:

 package cn.netjava.C_S.v3;
import java.awt.Color;
import java.awt.FlowLayout;
import java.io.IOException;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextArea;

public class ChatTools {
	//服务器显示框
	 static JTextArea information =new JTextArea(" ");
	 static JLabel count=   new JLabel();
	 static long history=0;
	//服务器内部用以保存所有客户线程对象的列表对象
	  static List<ChatThread> clientList=new ArrayList<ChatThread>();
		//1.根据用户名,密码认证用户的方法,如果认证通过,返回true;
		public static boolean authUser(String userName,String pwd){
			//返加Map中是否有这个用户名做key,这就要求用户名必须是唯一的
			return userInfoMap.containsKey(userName);
		}
		 //2.将一个连上来并通过认证的的客户机对象加入到队列中
		public static void addClient2Queue(ChatThread ct){
			clientList.add(ct);
			history++;
	       }
		//3.从队列中移除 用户名所代表的客户机对象
		public static void removeClient(String userName){
			for(int i=0;i<clientList.size();i++){
				ChatThread cs=clientList.get(i);
				if(cs.getUserName().equals(userName)){
					clientList.remove(i);
				}
			}
	       }
	     //4.调用后,将userName用户发的消息发给所有客户机
		 public static void castMsg(String userName,String msg){
			 for(int i=0;i<clientList.size();i++){
					ChatThread cs=clientList.get(i);
						cs.sendMsg2Me(userName+"说:"+msg+"\n");
				}
		}
		 
		 //服务器端用以保存用户名,密码的列表,表中的键为用户名,值为密码
	 private static Map<String,String> userInfoMap=new HashMap<String,String>(); 
	 //静态块:用做在系统初始时,初始化表户信息表中的用户名和密码,此处模拟生成数据
	 static { 
		 for(int i=0;i<10;i++){
			 String key="user"+i;
			 String value="pwd";
			 userInfoMap.put(key,value);
			 javax.swing.SwingUtilities.updateComponentTreeUI(ChatTools.information);
		 }
	 }
	 
	 public JFrame serverUI(){
		 JFrame serverFrame= new JFrame("多人聊天室服务器监控端");
		
		 count.setSize(800, 20);
		 serverFrame.setSize(800,600);
		 serverFrame.setDefaultCloseOperation(3);
		 serverFrame.setLayout(new FlowLayout());
		 information= new JTextArea(30,60);
		 information.setEditable(false);
		 information.setBackground(Color.decode("#33CCCC"));
		 information.setWrapStyleWord(true); 
		 serverFrame.add(count);
		 serverFrame.add(information);
		 
		 serverFrame.setVisible(true);
		 return serverFrame;
	 }

}

 日期格式处理代码:

package cn.netjava.C_S.v3;

import java.text.DateFormat;
import java.util.Date;

public class DateProcess {
	public String process(){
	DateFormat df = new java.text.SimpleDateFormat("yyyy年MM月dd日-hh:mm:ss");
	return df.format(new Date());
	}
 }

 连接处理线程类代码 

package cn.netjava.C_S.v3;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;

public class ChatThread extends Thread{
	//构造这个线程对象时,传客户机连结对象,在线程中处理.
	public ChatThread(Socket client){
		this.client=client;
	}
	public void run(){
		processClient(this.client);//调用处理客户端的方法
	}	
	//对外提供的调用接口,将消息发送给我代表的客户端
	public void sendMsg2Me(String msg){
		try{
			
		 ous.write((msg+"\r\n").getBytes());
		 
		 ous.flush();//将消息发送到客户机
		}catch(Exception ef){}
	}
	// 处理客户机连结对象socket
	private void processClient(java.net.Socket client){
		try{
			InputStream ins=   client.getInputStream();
			 ous=   client.getOutputStream();
			 
BufferedReader br=new BufferedReader(new InputStreamReader(ins));
			 //1.验证用户名和密码是否合格,如果不合格,则关闭连结,方法执行在此中断
			 String msg = "请输入用户名:";
			 sendMsg2Me(msg);
			 BufferedReader breader=new BufferedReader(new InputStreamReader(ins));
			 userName=breader.readLine();//读取用户输入的用户名,这个对象的userName属性赋上了值
			 			 msg="请输入你的密码:";
			 			 sendMsg2Me(msg);
			 			 String pwd=br.readLine();//读取用户输入的密码
			 			 //1.验证用户名和密码是否合格,如果不合格,则关闭连结,方法执行在此中断
			 			 if(!ChatTools.authUser(userName, pwd)){
			 				 msg="用户名或密码错!请询问管理员";
			 				 sendMsg2Me(msg);
			 				 client.close();
			 				 return ;
			 			 }

			 
			 ChatTools.addClient2Queue(this); //2.将这个线程对象放入服务器列表
			  String input="";
			  ChatTools.castMsg(userName,"我来啦!(已经加入本聊天室)");
			 ChatTools.count.setText("当前在线客户端: "+ChatTools.clientList.size()+" ,总共有  "+ChatTools.history +"个客户端连接过本服务器");
			  String temp = ChatTools.information.getText();
			  String time = (new DateProcess().process());
			  ChatTools.information.setText(temp+time+"------"+userName+" 已经与服务器建立连接...IP地址:  "
					  +client.getRemoteSocketAddress()+"\n");
			  javax.swing.SwingUtilities.updateComponentTreeUI(ChatTools.information);
			 //如果客户机发送 bye ,退出客户机
			 while(!input.equalsIgnoreCase("bye")){
			 input=br.readLine();//循环读取客户机的输入
			 ChatTools.castMsg(userName,input);//3.将读到的这条消息发送给客户机:
			  }
			 client.close();
		}catch(Exception ef){
			ef.printStackTrace();
		}
ChatTools.castMsg(userName,"我走了!(已经退出本聊天室)");

String temp = ChatTools.information.getText();
String time = (new DateProcess().process());
ChatTools.information.setText(temp+time+"------"+userName+" 已经与服务器断开连接...IP地址:  "
		  +client.getRemoteSocketAddress()+"\n");
javax.swing.SwingUtilities.updateComponentTreeUI(ChatTools.information);
ChatTools.removeClient(userName);//4.至此,这个客户机己退出,将其从列表中移除,
ChatTools.count.setText("当前在线客户端: "+ChatTools.clientList.size()+" ,总共有  "+ChatTools.history +"个客户端连接过本服务器");
	}
	
	//得到这个处理线程对象所代表客户机的用户名字
	public String getUserName(){
		return this.userName;
	}
	private String userName;//客户机名字,要在类中其它方法中调用,所以设置为属性
	private OutputStream ous;//输出流对象,要在类中其它方法中调用,所以设置为属性
	private Socket client;//客户机连结对象
	public Socket getClient() {
		return client;
	}
}
 
分享到:
评论

相关推荐

    用JavaSocket编程开发多人聊天室(群聊、私聊等)

    1. 用Java图形用户界面编写聊天室服务器端和客户端, 支持多个客户端连接到一个服务器。每个客户端能够输入账号。 2. 可以实现群聊(聊天记录显示在所有客户端界面)。 3. 完成好友列表在各个客户端上显示。 4. 可以...

    基于Linux操作系统C语言开发的多人聊天室程序设计与实现.docx

    里面附有源代码,加上详细的设计步骤,使用了C语言开发,功能有服务器和客户端的消息接收与发送,以及退出功能

    基于Python网络编程实现的多人聊天室项目源码+项目说明+超详细注释.zip

    基于Python网络编程实现的多人聊天室项目源码+项目说明+超详细注释.zip 基于Python网络编程的多人聊天室) ## 多人聊天室 1. 可以有多个客户端,每个客户端都有自己名字(唯一) 2. 客户端可以发送一条消息到聊天室...

    多人聊天室(Java版)

    多人聊天室程序,Java版,基于socket开发,可以在局域网内使用。本程序包括服务器端和客户端两部分。

    TCP/IP的多人聊天室程序源码

    1.加深对TCP/IP协议的理解; 2.掌握用Socket编程实现聊天工具。 3. visual studio2010提供了支持网络环境的类库system.net,可适应多种网络协议,包括TCP/IP、...4.程序包括服务器端程序,和客户端程序多人聊天系统

    局域网下多人聊天室_工程文档及图纸.rar

    本人于2021年毕业时所做毕设源码,为局域网条件下利用套接字通信的多人聊天室,开发语言为java,数据处理方面使用了MySQL,源码包含用户端(app)和服务器端两大部分,文档包含软件各部分功能逻辑流程图,由于当初没...

    TCP聊天室 VC版 含实验报告

    系统能实现简单的聊天室功能包括一对多,而且同时也支持一对一,即私聊功能。在系统运行中,用户可以随时更改自己的用户名。功能虽然单一但也能够满足聊天的基本功能。 二、 通信规范的制作 程序中定义了一个结构体...

    基于java的聊天室(socket)

    利用java语言和socket多线程及C/S模型的相关知识,开发一个具有良好人机界面的多人聊天室项目。 服务器端功能: 打开服务器端,开启服务器端,显示当前服务器状态 客户端功能: (1)通过页面实现账号的注册,然后...

    网络与通讯程序设计MyQQ聊天室

    MyQQ聊天室是仿照本程序制作的一个简单的单人或者多人聊天程序。本程序采用的通信协议以UDP为主,辅以TCP协议。采用C/S通信模式,把一个应用划分成两个部分,其中一个为服务器端,用来相应和提供固定的服务,另一个...

    HaiSpace聊天室(服务器+QT客户端)

    描述:在Fedora 14操作系统下,利用Ec lipse集成开发环境结合STL、网络编程、多线程技术编写服务器端C++代码,并通过OCCI访问orcl用户下的Oracle数据库对客户端连接的账号、密码进行检测;用QtCreator工具构建客户端...

    Java毕业设计-JAVA基于局域网的聊天室系统(源代码+论文).rar

    系统包括服务器端和客户端两部分,支持多人同时在线聊天,并具备基本的文本消息发送、接收以及文件传输功能。 **核心功能**: 1. **实时通信**:用户可在聊天室内实时发送和接收文本消息,实现即时沟通。 2. **...

    java开发C/S—聊天室

    1、基本功能:实现服务器监听,客户端连接,可进行多人会话的C/S聊天室。 2、服务器特点: 1)实现GUI界面,可选择端口运行或关闭服务器,可设置最大连接数 2)在GUI记录运行日志,同时日志被保存在log文件中 3)...

    java大作业设计报告-JAVA聊天室.doc

    JAVA程序设计 多人聊天室 设计目的 Java 编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高 性能、多线程和静态的语言。本次课程设计旨在应用JAVA编程语言中的网络通信,多线 程,...

    服务器架构方案总结.doc

    目前有以下几种网页游戏服务器: 1)FMS(Flash Media Server)用AS2.0或者AS1.0来构建服务器端的,而客户端可以用AS3.0。在视频方面比较 有优势,但是一般现在要结合其他语言开发比如NET类的。 flash聊天室啊,在线...

    java聊天室小程序+源代码

    今天把以前忘记的又看了一遍,这是一个java开发的聊天小程序,分为客户端和服务器端,我都是在本机上搞的,如果有局域网就把里面的client的IP改成运行server.jar的机子的IP,然后再打个jar包就可以了。运行时,必须...

    简易Web聊天

    Ajax实现的Web聊天页面,能实现多人同时在线聊天,服务器端采用Application记录,聊天大于100条,有人提交内容时会将内容自动缩减到最少可见条数,可以自行开发存储数据库或者xml文件的方法,代码十分简单,仅提供一...

    caldera-react:React的服务器端执行

    :volcano: Caldera是React的服务器端执行环境。 可以将其视为与Phoenix LiveView类似的Node.js,所有...一个简单的例子(聊天室)开始: import React , { useState } from "react" ; import { renderCalderaApp , ma

    RongKeMessenger-Server:RongKeMessenger for Server(融科通服务器端原始码)-源码通

    融科通是基于云视互动打造的前,后完全开源APP,除完善的APP框架和后台设计外,还涵盖了注册,登录,通讯录管理,单聊,群聊,音视频通话,多人语音聊天室等即时通讯互动功能,陆续融科通即将开始推出朋友圈,附近的...

    基于PHP实现的网上留言管理系统的设计(源代码+参考文献).zip

    网上留言系统的整体结构采用的是B/S(Browser/Server)应用架构,在这种架构下,软件应用的业务逻辑完全在应用服务器端实现,用户表现完全在Web服务器实现,客户端只需要浏览器即可进行业务处理。整个系统的设计...

    Java JDK实例宝典

    11 聊天室服务器端 13. 12 聊天室客户端 13. 13 FTP客户端 第14章 数据库 14. 1 连接各种数据库 14. 2 获得数据库和表的元数据 14. 3 查询和更新数据库 14. 4 批处理 14. 5 提交与...

Global site tag (gtag.js) - Google Analytics