时间:2018-12-01

概述:聊天室 服务器 客户端

在网络上经常进各种聊天室,本例通过编程实现了C/S 模式的聊天室服务器和客户端。实现方法:ChatServer 类实现了一个聊天室服务器端, 此类有一个构造器, 在构造器中使用newServerSocket()建立一个Socket 连接。RunServer()方法中运行聊天服务,通过Socket 类的getInetAddress().getHostName() 方法获得主机名, 建立新的ChatHandler 对象实例, 在synchronized (clients)中取得与客户端的同步。内部类ChatHandler 继承了Thread 类,在此线程run()方法中处理一次交谈。Close()方法关闭与客户端的连接。ChatRoom 类继承了Applet,在init()中通过new Frame()创建聊天窗体,并在此窗体中设置窗体布局。在login()方法中,通过new Socket(serverHost, port)建立与服务器的连接,通过new Thread()产生新的聊天线程。在logout()方法中,使用sock.close()关闭连接。程序代码:

1.编写Chat 类的基本框架,该类定义了从客户端到服务器的信息的第一个字节常量,该类还包括返回值为布尔型的isValidLoginName()方法,该方法用于判断登录名是否合法,代码如下:

public class Chat

{

public static final int PORTNUM = 9999;

public static final int MAX_LOGIN_LENGTH = 20;

public static final char SEPARATOR = '\\';

public static final char COMMAND = '\\';

public static final char CMD_LOGIN = 'L';

public static final char CMD_QUIT = 'Q';

public static final char CMD_MESG = 'M';

public static final char CMD_BCAST = 'B';

public static final char RESP_PUBLIC = 'P';

public static final char RESP_PRIVATE = 'M';

public static final char RESP_SYSTEM = 'S';

public static boolean isValidLoginName(String login)

{

if (login.length() > MAX_LOGIN_LENGTH)

return false;

return true;

}

}

2.编写ChatServer 类基本框架,该类为聊天室服务器程序。该类包括如下字段:字符串常量CHATMASTER_ID 和SEP,ServerSocket 对象变量servSock,ArrayList 对象变量clients,布尔型变量DEBUG。该类包括main()方法、构造器方法、runServer()方法、log()方法,该类还包括一个内部类ChatHandler,代码如下:

public class ChatServer

{

protected final static String CHATMASTER_ID = "ChatMaster";

protected final static String SEP = ": ";

protected ServerSocket servSock;

protected ArrayList clients;

private static boolean DEBUG = false;

//方法

public static void main(String[] argv);

ChatServer();

public void runServer();

protected void log(String s);

protected class ChatHandler extends Thread;

}

3.Main()方法用于构建一个ChatServer 类实例,运行服务器程序,代码如下:

public static void main(String[] argv)

{

System.out.println("Chat Server 0.1 starting...");

if (argv.length == 1 && argv[0].equals("-debug"))

DEBUG = true;

ChatServer w = new ChatServer();

w.runServer();

System.out.println("**ERROR* Chat Server 0.1 quitting");

}

4.ChatServer 的构造器用于构建该类实例,代码如下:

ChatServer()

{

clients = new ArrayList();

try

{

servSock = new ServerSocket(Chat.PORTNUM);

System.out.println("Chat Server Listening on port " + Chat.PORTNUM);

}

catch(IOException e)

{

log("IO Exception in ChatServer.");

System.exit(0);

}

}

5.RunServer()方法用于运行服务器程序:

public void runServer() {

try

{

while (true)

{

Socket us = servSock.accept();

String hostName = us.getInetAddress().getHostName();

System.out.println("Accepted from " + hostName);

ChatHandler cl = new ChatHandler(us, hostName);

synchronized (clients) {

clients.add(cl);

cl.start();

if (clients.size() == 1)

cl.send(CHATMASTER_ID, "Welcome! you're the first one here");

else {

cl.send(CHATMASTER_ID, "Welcome! you're the latest of " +clients.size() + " users.");

}

}

}

} catch(IOException e) {

log("IO Exception in runServer: " + e);

System.exit(0);

}

}

6.Log()方法用于输出字符串,代码如下:

protected void log(String s)

{

System.out.println(s);

}

7.编写内部类ChatHandler 的基本框架,该类用于处理每个交谈信息,该类继承了Thread 类,包括如下字段:Socket 对象变量clientSock,BufferedReader 对象变量is,PrintWriter 对象变量pw,字符串变量clientIP 和login,该类还包括构造器方法、run()方法、close()方法、send()方法、psend()方法、broadcast()方法、lookup()方法、toString()方法,代码如下:

protected class ChatHandler extends Thread {

protected Socket clientSock;

protected BufferedReader is;

protected PrintWriter pw;

protected String clientIP;

protected String login;

public ChatHandler(Socket sock, String clnt) throws IOException;

public void run();

protected void close();

public void send(String sender, String mesg);

protected void psend(String sender, String msg);

public void broadcast(String sender, String mesg);

protected ChatHandler lookup(String nick);

public String toString();

}

8.ChatHandler 构造器用于构建该类实例,代码如下:

public ChatHandler(Socket sock, String clnt) throws IOException

{

clientSock = sock;

clientIP = clnt;

is = new BufferedReader( new InputStreamReader(sock.getInputStream()));

pw = new PrintWriter(sock.getOutputStream(), true);

}

9.run()方法用于用于处理每一次交谈:

public void run()

{

String line;

try {

while ((line = is.readLine()) != null) {

char c = line.charAt(0);

line = line.substring(1);

switch (c) {

case Chat.CMD_LOGIN:

if (!Chat.isValidLoginName(line)) {

send(CHATMASTER_ID, "LOGIN " + line + " invalid");

log("LOGIN INVALID from " + clientIP);

continue;

}

login = line;

broadcast(CHATMASTER_ID, login + " joins us, for a total of " +clients.size() + " users");

break;

case Chat.CMD_MESG:

if (login == null) {

send(CHATMASTER_ID, "please login first");

continue;

}

int where = line.indexOf(Chat.SEPARATOR);

String recip = line.substring(0, where);

String mesg = line.substring(where+1);

log("MESG: " + login + "-->" + recip + ": "+ mesg);

ChatHandler cl = lookup(recip);

if (cl == null)

psend(CHATMASTER_ID, recip + " not logged in.");

else

cl.psend(login, mesg);

break;

case Chat.CMD_QUIT:

broadcast(CHATMASTER_ID, "Goodbye to " + login + "@" + clientIP);

close();

return;

case Chat.CMD_BCAST:

if (login != null)

broadcast(login, line);

else

log("B

break;

default:

log("Unknown cmd " + c + " from " + login + "@" + clientIP);

}

}

} catch (IOException e) {

log("IO Exception: " + e);

} finally {

System.out.println(login + SEP + "All Done");

synchronized(clients) {

clients.remove(this);

if (clients.size() == 0) {

System.out.println(CHATMASTER_ID + SEP +"Im so lonely I could cry...");

} else if (clients.size() == 1) {

ChatHandler last = (ChatHandler)clients.get(0);

last.send(CHATMASTER_ID,"Hey, you're talking to yourself again");

} else {

broadcast(CHATMASTER_ID,"There are now " + clients.size() + " users");

}

}

}

}

10.close()方法用于关闭服务器:

protected void close() {

if (clientSock == null) {

log("close when not open");

return;

}

try {

clientSock.close();

clientSock = null;

} catch (IOException e) {

log("Failure during close to " + clientIP);

}

}

11.Send()方法用于发送一条信息给用户,代码如下:

public void send(String sender, String mesg)

{

pw.println(sender + SEP + mesg);

}

12.Psend()方法用于发送一条私有信息给用户:

protected void psend(String sender, String msg)

{

send("", msg);

}

13.Broadcast()方法用于发送一条信息给所有用户:

public void broadcast(String sender, String mesg)

{

System.out.println("Broadcasting " + sender + SEP + mesg);

for (int i=0; i

ChatHandler sib = (ChatHandler)clients.get(i);

if (DEBUG)

System.out.println("Sending to " + sib);

sib.send(sender, mesg);

}

if (DEBUG) System.out.println("Done broadcast");

}

14.Lookup()方法用于与客户端同步:

protected ChatHandler lookup(String nick)

{

synchronized(clients) {

for (int i=0; i

ChatHandler cl = (ChatHandler)clients.get(i);

if (cl.login.equals(nick))

return cl;

}

}

return null;

}

15.toString()方法用于将ChatHandler 作为字符串返回:

public String toString()

{

return "ChatHandler[" + login + "]";

}

16.ChatServer 类应该引入如下包:

import java.io.*;

import java.net.*;

import java.util.*;

java c s聊天程序_Java建立C/S 模式聊天室服务器和客户端相关推荐

  1. 服务器发布程序打印不显示图片,用JAVA编写打印图片程序,调试的时候出现说“RPC 服务器不可用”,上面是具体的情况:(谢谢各位帮忙)...

    用JAVA编写打印图片程序,调试的时候出现说"RPC 服务器不可用",上面是具体的情况:(谢谢各位帮忙) 用JAVA编写打印图片程序,调试的时候出现说"RPC 服务器不可 ...

  2. java udp简单聊天程序_Java基于UDP协议实现简单的聊天室程序

    最近比较闲,一直在抽空回顾一些java方面的技术应用. 今天没什么事做,基于udp协议,写了一个非常简单的聊天室程序. 现在的工作,很少用到socket,也算是对java网络编程方面的一个简单回忆. ...

  3. java tcp聊天程序_java实现基于Tcp的socket聊天程序

    对于步入编程行业不深的初学者或是已经有所领会的人来说,当学习一项新的技术的时候,非常渴望有一个附上注释完整的Demo.本人深有体会,网上的例子多到是很多,但是很杂不完整,写代码这种东西来不得半点马虎, ...

  4. java socket编程实现聊天程序_java Socket编程 聊天程序 服务器端和客户端

    [java]代码库package com.gufengxiachen.sthreadchatapp; /** * @author GUXIA */ import java.io.BufferedRea ...

  5. 利用Java GUI,结合Java Socket,Java多线程,服务器,制作一个简单的具有界面的多用户实时聊天程序(从GUI,到Socket,到多线程,到服务器,项目级别详细教程)

    目录 规划 Java GUI设计 Java Socket Java 服务器 利用 IntelliJ IDEA软件为例 首先,我们应当了解,像运行在两台电脑或者手机终端这样的程序一般是没有办法直接相互发 ...

  6. java ee的小程序_Java EE调度程序

    java ee的小程序 Java EE应用程序服务器具有本机调度支持,并且在大多数应用程序中,不需要包括外部依赖项,例如著名的Quartz调度程序库. Java EE 6和7完整配置文件上提供的Jav ...

  7. java ee的小程序_Java EE应用程序的单片到微服务重构

    java ee的小程序 您是否曾经想过将现有的Java EE单体应用程序重构为基于微服务的应用程序需要做什么? 该博客说明了一个简单的购物车示例如何转换为基于微服务的应用程序,以及围绕它的一些担忧. ...

  8. java ee的小程序_Java EE 8 –为更多设备提供更多应用程序

    java ee的小程序 如果我不喜欢夏天的一件事,那就是事实是没有太多要分享或谈论的新闻. 谁决定将Java Day Tokyo置于今年的这个无聊的时间里,做得很好,并给了我一个写关于新的和即将到来的 ...

  9. java类和对象程序_Java类与对象程序设计基础

    Java类与对象程序设计基础 一.实验目的: 通过编制一个独立应用程序,使得学生掌握Java的系统所提供类的引用方法:通过编制一个完整的应用程序,使得学生对Java的应用程序的基本构成和基本算法熟练掌 ...

最新文章

  1. 凭着这把AutoML利剑,这家AI公司荣登 IEEE ISI“铁王座”
  2. 测试管理 | 4种优先级排序方法一定要掌握
  3. Java高级语法笔记-多个异常处理
  4. 在线mark.down编辑器
  5. 页面滚动可视区域的获取
  6. shell截取字符串的方法
  7. 密码学Cryptology
  8. 压缩文件下载后无法打开问题解决方法
  9. python语言mooc作业_计算机基础(Ⅱ)Python语言-中国大学mooc-试题题目及答案
  10. .NET Standard(1)——.NET Standard是什么
  11. 肯德基真的没有什么太多吃的谨慎洋…
  12. 程序员如何修炼自己的九阳神功
  13. Android本地文件存储,机身和外置sd卡
  14. 红蓝对抗场景下的二三事
  15. 国际炒黄金策略,炒黄金要怎么炒?
  16. 沙箱环境--虚拟环境
  17. 【元胞自动机】激进策略元胞自动机三车道(开放辅路,软件园影响)交通流模型matlab源码
  18. 笔记-迎难而上之Java基础进阶8
  19. java控制台_JAVA控制台输入输出方法总结
  20. Linux是干什么得?

热门文章

  1. 如何找到某个方法的声明
  2. 删除 setup.py 安装的 Python 软件包
  3. ios10 申请拍照权限_iOS10配置申请权限
  4. python语法箭头_Python中的函数注释:参数有冒号,声明后有- 箭头
  5. SQL脚本修改数据库名称
  6. 万人攻防大战:淘宝优惠活动,沦为黑产盛宴
  7. CSS自定义文件上传按钮
  8. MySQL 数据库插入速度调整
  9. C#颜色和名称样式对照表
  10. 软件测试 学习之路 CSS (三)