`

聊天室服务端Server

阅读更多
package chat;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;

/**
 * 聊天室服务端
 * @author adminitartor
 *
 */
public class Server {
	/*
	 * java.net.ServerSocket
	 * 用于向系统申请服务端口(客户端就是通过该端口
	 * 与服务端应用程序建立连接的)
	 * 监听服务端口,以接受客户端的连接。
	 */
	private ServerSocket server;
	/*
	 * 该集合存放所有客户端的输出流,以便广播消息
	 */
	private Map<String,PrintWriter> allOut;
	
	public Server() throws Exception{
		try {
			/*
			 * 创建时申请服务端口,不能与系统中
			 * 其他应用程序已使用端口冲突
			 * 否则抛出:
			 * AddressAlreadyInUser的错误
			 */
			server = new ServerSocket(8088);
			
			allOut = new HashMap<String,PrintWriter>();
		} catch (Exception e) {
			System.out.println("服务端初始化失败!");
			throw e;
		}
	}
	/**
	 * 将给定的某个客户端的输出流存入到共享集合
	 * @param out
	 */
	public synchronized void addOut(String nickName,PrintWriter out){
		allOut.put(nickName,out);
	}
	/**
	 * 将给定的客户端的输出流从共享集合中删除
	 * @param out
	 */
	public synchronized void removeOut(String nickName){
		allOut.remove(nickName);
	}
	/**
	 * 将给定的消息发送给所有客户端
	 * @param message
	 */
	public synchronized void sendMessage(String message){
		for(PrintWriter out : allOut.values()){
			out.println(message);
		}
	}
	/**
	 * 将指定消息发送给指定昵称的客户端
	 * @param nickName
	 * @param message
	 */
	public synchronized void sendMessage(String nickName,String message){
		PrintWriter out = allOut.get(nickName);
		if(out != null){
			out.println(message);
		}
	}
	
	
	public void start(){
		try {
			/*
			 * ServerSocket的accept方法是一个
			 * 阻塞方法,作用是监听申请的服务端口
			 * 直到一个客户端通过该端口与服务端
			 * 建立连接,accept方法才会执行完毕,
			 * 并返回一个Socket实例,通过这个Socket
			 * 可以与刚刚建立连接的客户端进行交互
			 */
			while(true){
				System.out.println("等待客户端连接...");
				Socket socket = server.accept();
				System.out.println("一个客户端连接了!");
				
				//启动线程处理该客户端交互
				ClientHandler handler
					= new ClientHandler(socket);
				Thread t = new Thread(handler);
				t.start();
				
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String[] args) {
		try {
			Server server = new Server();
			server.start();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * 该线程用来处理与服务端连接的一个客户端的
	 * 交互工作。
	 * @author adminitartor
	 *
	 */
	private class ClientHandler 
						implements Runnable{
		//当前线程通过该Socket与该客户端交互
		private Socket socket;
		//客户端的IP地址
		private String host;
		//用户昵称
		private String nickName;
		
		public ClientHandler(Socket socket){
			super();
			this.socket = socket;
		}
		
		public void run(){
			PrintWriter pw = null;
			try {
				//获取客户端IP地址
				InetAddress address 
					= socket.getInetAddress();
				//获取客户端IP地址的字符串形式
				host = address.getHostAddress();
				
				
				/*
				 * 想读取客户端发送过来的数据,需要通过
				 * Socket获取输入流。
				 */
				InputStream in 
					= socket.getInputStream();
				
				InputStreamReader isr
					= new InputStreamReader(in,"UTF-8");
				
				BufferedReader br
					= new BufferedReader(isr);
				
				//首先读取客户端发送过来的昵称
				nickName = br.readLine();
				sendMessage(nickName+"上线了...");
				
				/*
				 * 通过Socket获取输出流,以便将消息
				 * 发送给给客户端
				 */
				pw = new PrintWriter(
					new OutputStreamWriter(
						socket.getOutputStream(),"UTF-8"	
					),true	
				);
				//将该客户端的输出流存入共享集合
				addOut(nickName,pw);
				
				
				
				/*
				 * br.readLine方法在读取远端计算机发送过来的
				 * 一行字符串时,远端计算机断开连接后,其不同
				 * 的操作系统会影响这里readLine方法的结果。
				 * 当windows的客户端断开连接时:
				 * br.readLine方法会直接抛出异常
				 * 
				 * 当linux的客户端断开连接时:
				 * br.readLine方法会返回null
				 *
				 */
				String message = null;
				while((message = br.readLine())!=null){
//					System.out.println(host+"说:"+message);
//					pw.println(host+"说:"+message);
					//首先判断是否为私聊
					if(message.startsWith("@")){
						//先找到“:”的位置
						int index = message.indexOf(":");
						if(index<0){
							//告知当前客户端格式不对
							pw.println("私聊格式不对,私聊格式:@昵称:聊天内容");
						}else{
							//获取对方昵称
							String toNick = message.substring(1,index);
							//检查该用户是否存在:
							if(allOut.containsKey(toNick)){
								//获取聊天内容
								message = message.substring(index+1);
								sendMessage(toNick,nickName+"对你说:"+message);
							}else{
								pw.println("没有找到此用户:"+toNick);
							}
							
						}
					}else{
						//广播给所有客户端
						sendMessage(nickName+"说:"+message);
					}
				}
			} catch (Exception e) {
				
			} finally{
				//客户端断开后的处理
				
				//将该客户端的输出流从共享集合中删除
				removeOut(nickName);
				
				sendMessage(nickName+"下线了...");
				
				
				try {
					socket.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}
	
}





 

分享到:
评论

相关推荐

    server_多人聊天室服务端_源码

    【标题】"server_多人聊天室服务端_源码"涉及的核心知识点主要集中在Java编程语言、网络编程以及多线程技术。在这个项目中,开发者创建了一个可以支持多人同时在线聊天的服务端程序,允许用户通过客户端进行实时通信...

    基于.net聊天室服务端和客户端

    《基于.NET的聊天室服务端与客户端实现详解》 在当今信息技术高度发展的时代,网络通信技术扮演着至关重要的角色。本文将深入探讨一个基于.NET框架,利用Winform和Socket技术构建的聊天室服务端和客户端的实现过程...

    聊天室,服务端

    在计算机网络编程领域,聊天室服务端是一个关键的组件,它负责处理客户端的连接请求,接收并发送数据,实现用户间的实时通信。本项目是利用Visual Studio 2013的MFC(Microsoft Foundation Classes)库编写的一个...

    socket tcp聊天室server

    基于socket的tcp聊天室server demo

    socket实现简单聊天室功能 服务端和客户端代码

    本篇将深入探讨如何使用Socket实现一个简单的聊天室功能,包括服务端和客户端的代码实现。 一、Socket基础 Socket是网络通信的基本单元,它提供了进程间通信(IPC)的能力,尤其是跨越网络的进程间通信。在TCP/IP...

    网络聊天室chatserver.java

    标题中的"网络聊天室chatserver.java"指的是一个Java程序,用于建立一个网络聊天室服务端。这个服务端程序,通常称为服务器,是整个聊天系统的核心,它负责接收客户端的连接请求,处理通信,并将消息广播给其他在线...

    c# 局域网聊天室 客户端与服务端源代码

    《C#局域网聊天室:客户端与服务端源代码详解》 在计算机科学领域,网络编程是一项核心技能,尤其对于开发实时通信应用如聊天软件来说更是必不可少。本篇文章将深入探讨C#语言在局域网环境下的网络编程,特别关注...

    Python 聊天室 程序 客户端 服务端

    在Python编程领域,创建聊天室程序是学习网络通信和多线程等概念的良好实践。本项目包含客户端(Client.py)和服务端(Server.py),适用于初学者掌握基础的网络编程技能。我们将深入探讨这两个核心文件以及相关知识...

    聊天室 客户端 服务端程序

    在IT领域,构建一个聊天室客户端和服务端程序是学习网络通信和实时数据交换的重要实践。这个项目涵盖了多个关键知识点,包括网络编程、多线程、数据传输协议等。以下是这些核心概念的详细解释: 1. **网络编程**:...

    python写的socket聊天室程序,包括客户端和服务端

    在这个场景中,我们有一个基于Python编写的socket聊天室程序,它包含了客户端(client.py)和服务端(server.py)。这个程序允许多个客户端同时连接到服务端,进行双向的信息交流。这里我们将深入探讨涉及的Python...

    基于java server/socket 多线程技术的聊天室程序服务端。

    本程序通过结合Java的Socket编程和多线程技术实现了基本的聊天室服务端功能。它不仅支持多人群聊,还实现了简单的私聊功能。此外,通过扩展更多功能,如用户状态更新、消息记录等,可以进一步提升用户体验和服务质量...

    局域网聊天室(带客户端和服务端)

    ChatServer 聊天室服务端代码 Client 聊天室客户端代码 Bin 已编译程序 Web 聊天室浏览器端 配置如下: ①下载好Xampp并安装(http://sourceforge.net/projects/xampp/),然后将Web文件夹下的Chat文件夹里的内容...

    Python 聊天室 客户端和服务端 聊天 客服端与客户端聊天

    在聊天室项目中,我们通常会创建两个主要的部分:服务端(Server)和客户端(Client)。服务端负责监听来自客户端的连接请求,并管理多个客户端的连接,确保信息的正确传递。客户端则用来连接服务端,发送和接收消息...

    聊天室程序分为客户端和服务端

    本项目采用C#编程语言,将聊天室程序分为客户端(Client)和服务端(Server),以实现用户之间的实时交互。下面将详细阐述这两个主要组成部分以及相关的知识点。 1. **客户端(Client)**: - **网络通信库**:C#...

    基于QT实现的TCP聊天室 程序 有客户端 服务端

    在这个基于QT实现的TCP聊天室程序中,我们主要关注以下几个知识点: 1. **QT框架**:QT提供了丰富的库和工具,允许开发者使用C++编写应用程序,并能在Windows、Linux、macOS等不同操作系统上运行。它的核心特性包括...

    Java聊天程序服务端和客户端程序

    一个Java聊天程序服务端和客户端程序,C/S结构,ChatServer 类实现了一个聊天室服务器端, 此类有一个构造器, 在构造器中使用newServerSocket()建立一个Socket 连接。RunServer()方法中运行聊天服务,通过Socket 类...

    聊天室连接数据库的设计

    在文件`feixin Server`中,可能包含了聊天室服务端的实现代码,包括数据库连接、消息收发、用户管理等功能模块。通过对这些代码的学习和实践,您可以更深入地理解聊天室连接数据库的设计。 总之,设计一个聊天室...

    C#IM即时会议聊天服务端客户端源码

    【标题】:“C# IM即时会议聊天服务端客户端源码”是基于C#编程语言开发的一个即时通讯(Instant Messaging, IM)系统,主要用于实现实时的会议聊天功能。该系统包含服务端和客户端两部分,提供了在线交流和会议室...

    Ajax 聊天室,用JavaScript 调用WebServer 实现

    在这个.NET小例子中,我们使用Ajax构建了一个实时的聊天室,通过JavaScript与WebServer交互,实现了用户之间的即时通信。 一、Ajax基础 Ajax的核心是JavaScript异步通信,它通过XMLHttpRequest对象向服务器发送请求...

    仿QQ聊天室

    ChatServer可能包含了这些核心功能,开发者通过运行这个文件来启动聊天室的服务端,使得客户端可以连接并进行通信。 在这个仿QQ聊天室项目中,关键技术点可能包括: 1. **网络编程**:使用TCP或UDP协议建立客户端...

Global site tag (gtag.js) - Google Analytics