Java Socket实现多人聊天室

合集下载

socket编程聊天室基本流程

socket编程聊天室基本流程

socket编程聊天室基本流程一、引言Socket编程是一种用于网络通信的编程技术。

它允许程序员创建客户端和服务器应用程序,这些应用程序可以在不同的计算机上运行并通过Internet或局域网相互通信。

在本文中,我们将介绍Socket编程聊天室的基本流程。

二、Socket编程概述Socket编程是一种基于TCP/IP协议的网络编程技术。

它使用套接字(socket)来实现网络通信。

套接字是一种抽象概念,它表示一个网络连接点,可以用来发送和接收数据。

在Socket编程中,客户端和服务器之间建立一个连接,然后通过这个连接进行数据传输。

客户端向服务器发送请求,并等待服务器响应。

服务器接收请求并处理它,并将响应发送回客户端。

三、Socket编程聊天室基本流程1. 创建服务器程序首先,我们需要创建一个服务器程序来监听客户端连接请求。

在Python中,可以使用socket模块来创建套接字对象,并使用bind()方法将其绑定到指定的IP地址和端口号上。

2. 创建客户端程序然后,我们需要创建一个客户端程序来连接到服务器。

同样地,在Python中可以使用socket模块来创建套接字对象,并使用connect()方法连接到指定的IP地址和端口号上。

3. 实现消息传输一旦客户端和服务器之间建立了连接,它们就可以开始进行消息传输。

在Socket编程中,可以使用send()方法将数据发送到对方,使用recv()方法从对方接收数据。

4. 实现聊天室功能为了实现聊天室功能,我们需要让多个客户端能够同时连接到服务器,并且能够相互通信。

为此,我们可以使用多线程或异步编程技术来实现。

在多线程模式下,每个客户端连接都会被分配一个独立的线程来处理。

这个线程负责接收客户端发送的消息,并将其转发给其他客户端。

在异步编程模式下,我们可以使用协程或回调函数来处理消息传输。

当有新的消息到达时,就会触发相应的回调函数进行处理。

5. 实现用户管理为了实现用户管理功能,我们需要让每个客户端都能够注册一个唯一的用户名,并且能够查看当前在线的用户列表。

多人聊天室编码项目摘要

多人聊天室编码项目摘要

多人聊天室编码项目摘要项目摘要有:一、设计内容利用java语言实现聊天室程序。

聊天室分为服务器端和客户端两部分,服务器端程序主要负责侦听客户端发来的消息,客户端需登录到服务器端才可以实现正常的聊天功能。

设计的聊天室能实现用户登录,显示登录用户列表,以及发送聊天信息和显示聊天信息的功能。

并可以选择接收信息的用户进行单发或群发的功能,运行程序,登录服务器后,可以从列表中选择单个或多个用户进行聊天,它是图形界面,线程,流与文件系统等技术的综合应用。

二、实现功能1、启动服务器端,接收客户端发来的信息,并在服务器端窗体显示客户端聊天信息,再吧信息返给在线用户。

2、启动客户端,进入客户端页面,输入用户名,点击登录按钮,在显示在线用户列表内显示用户名。

3、发送编辑框输入发送内容,单击发送按钮,启动输出流,把信息发送出去,同时把发出的信息追加到聊天内容文本域内,显示用户名,时间和发送内容。

4、聊天信息文本域,在线用户显示域和发送信息的文本域加了滚动条,其中聊天信息文本域,发送信息的文本域的文字能自动换行。

5、别的客户端发来信息是通过输入流读取信息,并截取发来信息的用户名及信息,用户名加到在线用户列表上显示在线,信息追加到聊天内容文本域内,显示用户名,时间和发送内容。

三、开发环境选择1、就执行平台而言,必须考虑的问题之一是用户可能使用的操作系统。

用户可能使用的是Windows Linux。

JAVA语言具有平台无关性,可以不需要任何修改就可以运行在支持JAVA的任何计算机上。

2、JAVA的Swing 组件开发技术可以开发丰富的图形界面,并且Swing API 类提供了丰富的外部接口和方法,可以方便实现系统功能。

3、就项目开发而言,纯粹的面向对象,加上数量巨大的类所提供的方法(函数)库的支持,使得利用Java开发各种应用程序,可以说是易如反掌。

此外,在程序除错、修改、升级和增加新功能等方面,因其面向对象的特性,使得这些维护也变得非常容易。

SimpleChat程序(一对多聊天源代码 java)

SimpleChat程序(一对多聊天源代码 java)

package com.wyh.chatRoom;import java.awt.BorderLayout;import java.awt.Color;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.io.PrintWriter;import .InetAddress;import .ServerSocket;import .Socket;import javax.swing.JButton;import javax.swing.JComboBox;import javax.swing.JFrame;import javax.swing.JLabel;import javax.swing.JPanel;import javax.swing.JScrollPane;import javax.swing.JTabbedPane;import javax.swing.JTextArea;import javax.swing.JTextField;import javax.swing.JToolBar;public class wyhChatRoom extends JFrame implements ActionListener{ private String name; //服务器聊天室的图形用户界面private JComboBox combox; //网名private JTextField text; //输入IP地址或域名的组合框private JTabbedPane tab; //选项卡窗格,每页与一个Socket通信public wyhChatRoom(int port ,String name) throws IOException{super("聊天室"+name+" "+InetAddress.getLocalHost()+"端口:"+port);this.setBounds(320, 240, 440, 240);this.setDefaultCloseOperation(EXIT_ON_CLOSE);JToolBar toolbar=new JToolBar(); //工具栏this.getContentPane().add(toolbar,"North");toolbar.add(new JLabel("主机"));combox=new JComboBox();combox.addItem("127.0.0.1");toolbar.add(combox);combox.setEditable(true);toolbar.add(new JLabel("端口"));text=new JTextField("1251");toolbar.add(text);JButton button_connect=new JButton("连接");button_connect.addActionListener(this);toolbar.add(button_connect);tab=new JTabbedPane(); //选项卡窗口this.setBackground(Color.blue);this.getContentPane().add(tab);this.setVisible(true);=name;while(true){Socket client=new ServerSocket(port).accept();//等待接受客户端的连接申请tab.addTab(name, new TabPageJPanel(client));//tab添加页,页中添加内部类面板tab.setSelectedIndex(tab.getTabCount()-1);//tab指定新页为选择状态port++;}}public void actionPerformed(ActionEvent e){if(e.getActionCommand()=="连接"){String host=(String)combox.getSelectedItem();int port=Integer.parseInt(text.getText());try{tab.addTab(name, new TabPageJPanel(new Socket(host,port)));//连接成功tab添加页tab.setSelectedIndex(tab.getTabCount()-1);//tab指定新页为选中状态}catch(IOException e1){e1.printStackTrace();}}}//面板内部类,每个对象表示选项卡窗格的一页,包含一个Socket和一个线程private class TabPageJPanel extends JPanel implements Runnable,ActionListener{Socket socket;Thread thread;JTextArea text_receiver;//显示对话内容的文本区JTextField text_sender; //输入发送内容的文本行JButton buttons[]; //发送‘离线’删除页按钮PrintWriter cout; //字符输出流对象int index;TabPageJPanel(Socket socket) {super(new BorderLayout());this.text_receiver=new JTextArea();this.text_receiver.setEditable(false);this.add(new JScrollPane(this.text_receiver));JPanel panel=new JPanel();this.add(panel,"South");this.text_sender=new JTextField(16);panel.add(this.text_sender);this.text_sender.addActionListener(this);String strs[]={"发送","离线","删除页"};buttons =new JButton[strs.length];for (int i = 0; i < buttons.length; i++) {buttons[i]=new JButton(strs[i]);panel.add(buttons[i]);buttons[i].addActionListener(this);}buttons[2].setEnabled(false);this.socket=socket;this.thread=new Thread(this);this.thread.start();}@Overridepublic void run() {try {this.cout =new PrintWriter(socket.getOutputStream(),true);this.cout.println(name);//发送自己网名给对方BufferedReader cin=new BufferedReader(new InputStreamReader(socket.getInputStream()));String name=cin.readLine(); //接收对方网名index=tab.getSelectedIndex();tab.setTitleAt(index, name);String aline=cin.readLine();while(aline!=null && !aline.equals("bye")){tab.setSelectedIndex(index);text_receiver.append(aline+"\r\n");Thread.sleep(1000);aline=cin.readLine();}cin.close();cout.close();socket.close();buttons[0].setEnabled(false);//接收方的发送按钮无效buttons[1].setEnabled(false);//接收方的离线按钮无效buttons[2].setEnabled(false);//接收方的删除按钮无效} catch (Exception e) {e.printStackTrace();}}@Overridepublic void actionPerformed(ActionEvent e) {if(e.getActionCommand()=="发送"){this.cout.println(name+"说:"+text_sender.getText());text_receiver.append("我说:"+text_sender.getText()+"\n");text_sender.setText("");}if(e.getActionCommand()=="离线"){text_receiver.append("我离线\n");this.cout.println(name+"离线\n"+"bye");buttons[0].setEnabled(false);buttons[1].setEnabled(false);buttons[2].setEnabled(false);}}}public static void main(String[] args) throws IOException {new wyhChatRoom(2001, "航哥哥");//启动服务端,约定端口,指定网名}}。

基于Java Socket的聊天室系统设计与实现

基于Java Socket的聊天室系统设计与实现
Absr c : n o o k ti ewo k p o r mmig it ra e T i a e nto u e h c a im t a t Wi d ws S c e sa n t r r g a n ne fc . h sp p ri r d c d t e me h n s
户端根据输入 Sr r I e e 的 P地址连入相应的服务器参与聊天活动, v 服务器上显示当前在线的用户信
息 , 对用户进 入或 断开 的信 息加 以显示。 并 关键词 :aa 接 字 ; Jv 套 聊天 室 ; 户端 ; 客 服务器
D I 码 : .9 9 ii n 1 0 2 7 .0 0 0 . 1 O编 1 3 6 /.s . 0 2— 2 9 2 1 .5 0 9 0 s
中图分 类号 :P 9 T 33
文献标识 码 : A
文章编号 :0 2— 2 9 2 1 )5— 0 6— 2 10 2 7 (0 0 O 0 6 0
De in & I lme to a y t m a e n J v c e sg mpe n fCh tS se B s d o a a So k t
ci t o n c dwt cm a besr r n ie h tn codn eI f e e i ut .nte l n cn et i o p t l ev dj ndcat gacri t t Po r r n t d I h e e h i ea o i goh sv p e
H ig j g L a g h n U J — i ,U M n — og n n
( u a io i l n l t m ca i l o t h i, h nsa4 0 2 ,hn ) H n nBo gc dEe r eh n a le n C a gh 1 16 C i l aa co c P yc c a

用Java Socket实现网络聊天室

用Java Socket实现网络聊天室

务的端 口为8 端 口. e n t 2 端 口, 0 t le 为 3 f p为 2 端 口。通常.从 0 1 2 t 1 — 0 3的端
程序使用 。
L号为系统保 留.大于 1 2 『 0 3提供给应 用 F i t t e m( e rnSra nw
B f e e o tu S r a u f r d u p t t em
t ryi
首先 分析一下聊天室的基 本功能 需

操 作系统的通 用网络编程标准 。在 网络 编程中最常用的方案便是客户 / 务器模 服 型。奉文提 出了在客户机 /服务器 模型 下用 j v o k t a a sc e 实现 I t r e n en t巾常见 的聊天 室软件 的解 决方案 。 Sc e o k t简介
e :
户 当用 户差 闭客 户 端退 出时 . 结束
与用户的 会话 .在服务器端注 销此用 户 2.客户 端 :提 供 良好 的用户 界 面 . 便 于用 户 进 行 连接 、交 谈 当与
个 具有 S c e 接 口的计算机通信 。『 okt 盏用 程序在 网络上传输 ,接收 的信 息都通过 这个 S c e 接 口来 实现 。在应 用开发中 okt
S s e u . r a l (E r r y tm o t p it n r o : e: )
端 有无 数据 发 出, 如有 则接 收数 据 , 更新显示 。 四 、聊 天室应 用程 序类音 规 划 9
经过分析 笔者主 要确定 了如下类 :
服务器端 :

如睹络上最通用 的 t 1 e 、f p等 .就 en t t 如主机 接收 到此请求 .则通信 建 是基于 s c e o k t的服 务程序 ,同一 台主机 立 .服务端产 生一个 S c e o k t实例 .同 可 以提供 多种 服 务,但他 们 并不冲 突 . 此 客 户端 进 行 通 信 ,如 上 。 只因为他们的通信端 口不同,如 h t t p服 然后客户端和服务端分别打 开相 应 的输入输 出流 进行数据 传送 。

多人聊天系统的设计与实现

多人聊天系统的设计与实现

多人聊天系统的设计与实现1.系统设计:a.客户端设计:客户端需要有用户界面用于用户输入和显示聊天内容。

用户界面应该支持多人聊天,因此可以设计为一个聊天室的形式,让用户能够选择加入不同的聊天室。

客户端还需要处理消息的发送和接收,并将接收到的消息显示在用户界面上。

b.服务器设计:服务器用于协调客户端之间的通信。

服务器需要根据客户端的请求,将消息发送给指定的客户端。

服务器还需要管理聊天室的创建和销毁,以及处理用户的连接和断开。

2.系统实现:a. 客户端实现:客户端可以使用常见的编程语言(如Python、Java、C++等)进行实现。

客户端需要使用套接字(socket)进行与服务器的通信,并实现发送和接收消息的功能。

客户端还需要设计用户界面以便于用户进行输入和显示聊天内容。

b.服务器实现:服务器也可以使用常见的编程语言进行实现。

服务器需要使用套接字进行与客户端的通信,并维护一个客户端列表用于管理连接的客户端。

服务器需要处理客户端的连接和断开,并根据客户端的请求发送相应的消息给指定的客户端。

3.其他功能的设计与实现:a.聊天记录保存:可以设计一个数据库用于保存聊天记录,以便于用户离线时能够查看历史消息。

b.文件传输:可以设计一个文件传输功能,允许用户发送和接收文件。

c.图片和表情支持:可以设计一个图片和表情支持的功能,允许用户发送和接收图片和表情。

d.用户认证与权限管理:可以设计一个用户认证和权限管理的功能,以确保只有经过认证的用户才能加入聊天室,并按照权限进行相关操作。

e.客户端扩展性:可以设计客户端的扩展性,以便于在未来可以添加更多的功能和插件。

以上是多人聊天系统的设计与实现的一个基本框架和示例。

具体的实现方式和细节可以根据具体的需求来设计和开发。

基于websocket和java的多人聊天室

基于websocket和java的多人聊天室

最新基于websocket与java的多人聊天室实现架构html5+websocket+javaEE7+tomcat8JavaEE7 最新的websocket1.0 APITomcat8开始支持websocket1.0 API【Tomcat implements the Java WebSocket 1.0 API defined by JSR-356】在编写代码之前你要导入javaEE7的jar包以便使用websocket API,将此项目部署到tomcat8里面。

具体代码如下:Java端:ChatAnnotation类;使用的是注解的方式。

package websocket.chat;import java.io.IOException;import java.util.Set;import java.util.concurrent.CopyOnWriteArraySet;import java.util.concurrent.atomic.AtomicInteger;import javax.websocket.OnClose;import javax.websocket.OnError;import javax.websocket.OnMessage;import javax.websocket.OnOpen;import javax.websocket.Session;import javax.websocket.server.ServerEndpoint;import org.apache.juli.logging.Log;import org.apache.juli.logging.LogFactory;import util.HTMLFilter;@ServerEndpoint(value = "/websocket/chat")public class ChatAnnotation {private static final Log log =LogFactory.getLog(ChatAnnotation.class);private static final String GUEST_PREFIX = "Guest";private static final AtomicInteger connectionIds = new AtomicInteger(0);private static final Set<ChatAnnotation> connections =new CopyOnWriteArraySet<>();private final String nickname;private Session session;public ChatAnnotation() {nickname = GUEST_PREFIX + connectionIds.getAndIncrement(); }@OnOpenpublic void start(Session session) {this.session = session;connections.add(this);String message = String.format("* %s %s", nickname, "has joined.");broadcast(message);}@OnClosepublic void end() {connections.remove(this);String message = String.format("* %s %s",nickname, "has disconnected.");broadcast(message);}@OnMessagepublic void incoming(String message) {// Never trust the clientString filteredMessage = String.format("%s: %s",nickname, HTMLFilter.filter(message.toString()));broadcast(filteredMessage);}@OnErrorpublic void onError(Throwable t) throws Throwable {log.error("Chat Error: " + t.toString(), t);}private static void broadcast(String msg) {for (ChatAnnotation client : connections) {try {synchronized (client) {client.session.getBasicRemote().sendText(msg);}} catch (IOException e) {log.debug("Chat Error: Failed to send message to client", e);connections.remove(client);try {client.session.close();} catch (IOException e1) {// Ignore}String message = String.format("* %s %s",client.nickname, "has been disconnected."); broadcast(message);}}}}里面的juli.jar包可以百度一下自行下载。

Java课程设计聊天室(含代码)

Java课程设计聊天室(含代码)

Java程序课程设计任务书JAVA聊天室的系统的设计与开发1.主要内容:用JAVA实现基于C/S模式的聊天室系统。

聊天室分为服务器端和客户端两部分,服务器端程序主要负责侦听客户端发来的信息,客户端需要登陆到服务器端才可以实现正常的聊天功能。

2.具体要求(包括技术要求等):系统的功能要求:A.服务器端主要功能如下:1.在特定端口上进行侦听,等待客户端连接。

2.用户可以配置服务器端的侦听端口,默认端口为8888。

3.向已经连接到服务器端的用户发送系统消息。

4.统计在线人数。

5.当停止服务时,断开所有的用户连接。

B.客户端的主要功能如下:1.连接到已经开启聊天服务的服务器端。

2.用户可以配置要连接的服务器端的IP地址和端口号。

3.用户可以配置连接后显示的用户名。

4.当服务器端开启的话,用户可以随时登录和注销。

5.用户可以向所有人或某一个人发送消息。

学习并掌握一下技术:Java JavaBean 等熟练使用一下开发工具:Eclipse, JCreator 等实现系统上诉的功能。

3.进度安排:12月28日 ~ 12月29日:课程设计选题,查找参考资料12月30日 ~ 1月1日:完成系统设计1月2日 ~ 1月5日:完成程序代码的编写1月6日:系统测试与完善1月7日:完成课程设计报告,准备答辩4.主要参考文献:[1].张广彬孟红蕊张永宝.Java课程设计(案例精编)[M].清华大学出版社.2007年版摘要在网络越来越发达的今天,人们对网络的依赖越来越多,越来越离不开网络,由此而产生的聊天工具越来越多,例如,国外的ICQ、国内腾讯公司开发的OICQ。

基于Java网络编程的强大功能,本次毕业设计使用Java编写一个聊天系统。

一般来说,聊天工具大多数由客户端程序和服务器程序外加服务器端用于存放客户数据的数据库组成,本系统采用客户机/服务器架构模式通过Java提供的Soket类来连接客户机和服务器并使客户机和服务器之间相互通信,由于聊天是多点对多点的而Java提供的多线程功能用多线程可完成多点对多点的聊天,数据库管理系统用SQL Server2000完成并通过JDBC-ODBC桥访问数据库。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

Java Socket实现多人聊天室---swing做UI标签:socket聊天javaexception服务器string2011-08-31 15:06 20679人阅读评论(25) 收藏举报分类:java(21)版权声明:本文为博主原创文章,未经博主允许不得转载。

今天翻硬盘的workspace发现一个Java Socket实现多人聊天室的源码,不记得是什么时候的事情了,貌似不是我写的。

但写得还不错,至少算个有模有样的聊天室工具。

我简单的修改了一下,拿出来跟大家分享一下,仅供参考。

界面是用swing写的,还不懒,简约大方。

有图有真相:正如上图所示,这个程序分为服务器端和客户端,说白了就是两个main class,用eclipse 直接运行之。

聊天室的设计思想是:在局域网下,利用socket进行连接通信,当服务器端启动的时候,利用Thread线程不停的等待客户端的链接;当有客户端开启连接的时候,服务器端通过IO流反馈“上线用户”信息给客户端,客户端也使用线程不停的接收服务器的信息,从而实现多人在线聊天功能。

程序中有三个类,分别Server.java(服务器端)、Client(客户端)、User.java(javabean)。

代码如下:Server.java(服务器端):[html]view plaincopy1.import java.awt.BorderLayout;2.import java.awt.Color;3.import java.awt.GridLayout;4.import java.awt.Toolkit;5.import java.awt.event.ActionEvent;6.import java.awt.event.ActionListener;7.import java.awt.event.WindowAdapter;8.import java.awt.event.WindowEvent;9.import java.io.BufferedReader;10.i mport java.io.IOException;11.i mport java.io.InputStreamReader;12.i mport java.io.PrintWriter;13.i mport .BindException;14.i mport .ServerSocket;15.i mport .Socket;16.i mport java.util.ArrayList;17.i mport java.util.StringTokenizer;18.19.i mport javax.swing.DefaultListModel;20.i mport javax.swing.JButton;21.i mport javax.swing.JFrame;22.i mport javax.swing.JLabel;23.i mport javax.swing.JList;24.i mport javax.swing.JOptionPane;25.i mport javax.swing.JPanel;26.i mport javax.swing.JScrollPane;27.i mport javax.swing.JSplitPane;28.i mport javax.swing.JTextArea;29.i mport javax.swing.JTextField;30.i mport javax.swing.border.TitledBorder;31.32.p ublic class Server {33.34. private JFrame frame;35. private JTextArea contentArea;36. private JTextField txt_message;37. private JTextField txt_max;38. private JTextField txt_port;39. private JButton btn_start;40. private JButton btn_stop;41. private JButton btn_send;42. private JPanel northPanel;43. private JPanel southPanel;44. private JScrollPane rightPanel;45. private JScrollPane leftPanel;46. private JSplitPane centerSplit;47. private JList userList;48. private DefaultListModel listModel;49.50. private ServerSocket serverSocket;51. private ServerThread serverThread;52. private ArrayList<ClientThread> clients;53.54. private boolean isStart = false;55.56. // 主方法,程序执行入口57. public static void main(String[] args) {58. new Server();59. }60.61. // 执行消息发送62. public void send() {63. if (!isStart) {64. JOptionPane.showMessageDialog(frame, "服务器还未启动,不能发送消息!", "错误",65. JOptionPane.ERROR_MESSAGE);66. return;67. }68. if (clients.size() == 0) {69. JOptionPane.showMessageDialog(frame, "没有用户在线,不能发送消息!", "错误",70. JOptionPane.ERROR_MESSAGE);71. return;72. }73. String message = txt_message.getText().trim();74. if (message == null || message.equals("")) {75. JOptionPane.showMessageDialog(frame, "消息不能为空!", "错误",76. JOptionPane.ERROR_MESSAGE);77. return;78. }79. sendServerMessage(message);// 群发服务器消息80. contentArea.append("服务器说:" + txt_message.getText() + "\r\n");81. txt_message.setText(null);82. }83.84. // 构造放法85. public Server() {86.frame = new JFrame("服务器");87. // 更改JFrame的图标:88. //frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Client.class.getResource("qq.png")));89. frame.setIconImage(Toolkit.getDefaultToolkit().createImage(Server.class.getResource("qq.png")));90.contentArea = new JTextArea();91. contentArea.setEditable(false);92. contentArea.setForeground(Color.blue);93.txt_message = new JTextField();94.txt_max = new JTextField("30");95.txt_port = new JTextField("6666");96.btn_start = new JButton("启动");97.btn_stop = new JButton("停止");98.btn_send = new JButton("发送");99. btn_stop.setEnabled(false);100.listModel = new DefaultListModel();erList = new JList(listModel);102.103.southPanel = new JPanel(new BorderLayout()); 104. southPanel.setBorder(new TitledBorder("写消息")); 105. southPanel.add(txt_message, "Center");106. southPanel.add(btn_send, "East");107.leftPanel = new JScrollPane(userList);108. leftPanel.setBorder(new TitledBorder("在线用户"));109.110.rightPanel = new JScrollPane(contentArea);111. rightPanel.setBorder(new TitledBorder("消息显示区"));112.113.centerSplit = new JSplitPane(JSplitPane.HORIZONTAL _SPLIT, leftPanel,114. rightPanel);115. centerSplit.setDividerLocation(100);116.northPanel = new JPanel();117. northPanel.setLayout(new GridLayout(1, 6)); 118. northPanel.add(new JLabel("人数上限"));119. northPanel.add(txt_max);120. northPanel.add(new JLabel("端口"));121. northPanel.add(txt_port);122. northPanel.add(btn_start);123. northPanel.add(btn_stop);124. northPanel.setBorder(new TitledBorder("配置信息"));125.126. frame.setLayout(new BorderLayout());127. frame.add(northPanel, "North");128. frame.add(centerSplit, "Center");129. frame.add(southPanel, "South");130. frame.setSize(600, 400);131. //frame.setSize(Toolkit.getDefaultToolkit().getScr eenSize());//设置全屏132. int screen_width = Toolkit.getDefaultToolkit().get ScreenSize().width;133. int screen_height = Toolkit.getDefaultToolkit().ge tScreenSize().height;134. frame.setLocation((screen_width - frame.getWidth() ) / 2,135. (screen_height - frame.getHeight()) / 2);136. frame.setVisible(true);137.138. // 关闭窗口时事件139. frame.addWindowListener(new WindowAdapter() { 140. public void windowClosing(WindowEvent e) { 141. if (isStart) {142. closeServer();// 关闭服务器143. }144. System.exit(0);// 退出程序145. }146. });147.148. // 文本框按回车键时事件149. txt_message.addActionListener(new ActionListener() {150. public void actionPerformed(ActionEvent e) { 151. send();152. }153. });154.155. // 单击发送按钮时事件156. btn_send.addActionListener(new ActionListener() {157. public void actionPerformed(ActionEvent arg0) {158. send();159. }160. });161.162. // 单击启动服务器按钮时事件163. btn_start.addActionListener(new ActionListener() {164. public void actionPerformed(ActionEvent e) { 165. if (isStart) {166. JOptionPane.showMessageDialog(frame, "服务器已处于启动状态,不要重复启动!",167. "错误", JOptionPane.ERROR_MESSAGE);168. return;169. }170. int max;171. int port;172. try {173. try {174.max = Integer.parseInt(txt_max.get Text());175. } catch (Exception e1) {176. throw new Exception("人数上限为正整数!");177. }178. if (max <= 0) {179. throw new Exception("人数上限为正整数!");180. }181. try {182.port = Integer.parseInt(txt_port.g etText());183. } catch (Exception e1) {184. throw new Exception("端口号为正整数!");185. }186. if (port <= 0) {187. throw new Exception("端口号为正整数!");188. }189. serverStart(max, port);190. contentArea.append("服务器已成功启动!人数上限:" + max + ",端口:" + port191. + "\r\n");192. JOptionPane.showMessageDialog(frame, "服务器成功启动!");193. btn_start.setEnabled(false);194. txt_max.setEnabled(false);195. txt_port.setEnabled(false);196. btn_stop.setEnabled(true);197. } catch (Exception exc) {198. JOptionPane.showMessageDialog(frame, e xc.getMessage(),199. "错误", JOptionPane.ERROR_MESSAGE);200. }201. }202. });203.204. // 单击停止服务器按钮时事件205. btn_stop.addActionListener(new ActionListener() {206. public void actionPerformed(ActionEvent e) { 207. if (!isStart) {208. JOptionPane.showMessageDialog(frame, "服务器还未启动,无需停止!", "错误",209. JOptionPane.ERROR_MESSAGE); 210. return;211. }212. try {213. closeServer();214. btn_start.setEnabled(true);215. txt_max.setEnabled(true);216. txt_port.setEnabled(true);217. btn_stop.setEnabled(false);218. contentArea.append("服务器成功停止!\r\n");219. JOptionPane.showMessageDialog(frame, "服务器成功停止!");220. } catch (Exception exc) {221. JOptionPane.showMessageDialog(frame, "停止服务器发生异常!", "错误",222. JOptionPane.ERROR_MESSAGE); 223. }224. }225. });226. }227.228. // 启动服务器229. public void serverStart(int max, int port) throws java .net.BindException {230. try {231.clients = new ArrayList<ClientThread>();232.serverSocket = new ServerSocket(port); 233.serverThread = new ServerThread(serverSocket, max);234. serverThread.start();235.isStart = true;236. } catch (BindException e) {237.isStart = false;238. throw new BindException("端口号已被占用,请换一个!");239. } catch (Exception e1) {240. e1.printStackTrace();241.isStart = false;242. throw new BindException("启动服务器异常!"); 243. }244. }245.246. // 关闭服务器247. @SuppressWarnings("deprecation")248. public void closeServer() {249. try {250. if (serverThread != null)251. serverThread.stop();// 停止服务器线程252.253. for (int i = clients.size() - 1; i >= 0; i--) {254. // 给所有在线用户发送关闭命令255. clients.get(i).getWriter().println("CLOSE");256. clients.get(i).getWriter().flush(); 257. // 释放资源258. clients.get(i).stop();// 停止此条为客户端服务的线程259. clients.get(i).reader.close();260. clients.get(i).writer.close();261. clients.get(i).socket.close();262. clients.remove(i);263. }264. if (serverSocket != null) {265. serverSocket.close();// 关闭服务器端连接266. }267. listModel.removeAllElements();// 清空用户列表268.isStart = false;269. } catch (IOException e) {270. e.printStackTrace();271.isStart = true;272. }273. }274.275. // 群发服务器消息276. public void sendServerMessage(String message) { 277. for (int i = clients.size() - 1; i >= 0; i--) { 278. clients.get(i).getWriter().println("服务器:" + message + "(多人发送)");279. clients.get(i).getWriter().flush();280. }281. }282.283. // 服务器线程284. class ServerThread extends Thread {285. private ServerSocket serverSocket;286. private int max;// 人数上限287.288. // 服务器线程的构造方法289. public ServerThread(ServerSocket serverSocket, int max) {290.this.serverSocket = serverSocket;291.this.max = max;292. }293.294. public void run() {295. while (true) {// 不停的等待客户端的链接296. try {297. Socket socket = serverSocket.accept();298. if (clients.size() == max) {// 如果已达人数上限299. BufferedReader r = new BufferedRea der(300. new InputStreamReader(sock et.getInputStream()));301. PrintWriter w = new PrintWriter(so cket302. .getOutputStream()); 303. // 接收客户端的基本用户信息304. String inf = r.readLine();305. StringTokenizer st = new StringTok enizer(inf, "@");306. User user = new User(st.nextToken( ), st.nextToken());307. // 反馈连接成功信息308. w.println("MAX@服务器:对不起," + user.getName()309. + user.getIp() + ",服务器在线人数已达上限,请稍后尝试连接!");310. w.flush();311. // 释放资源312. r.close();313. w.close();314. socket.close();315. continue;316. }317. ClientThread client = new ClientThread (socket);318. client.start();// 开启对此客户端服务的线程319. clients.add(client);320. listModel.addElement(client.getUser().getName());// 更新在线列表321. contentArea.append(client.getUser().ge tName()322. + client.getUser().getIp() + "上线!\r\n");323. } catch (IOException e) {324. e.printStackTrace();325. }326. }327. }328. }329.330. // 为一个客户端服务的线程331. class ClientThread extends Thread {332. private Socket socket;333. private BufferedReader reader;334. private PrintWriter writer;335. private User user;336.337. public BufferedReader getReader() {338. return reader;339. }340.341. public PrintWriter getWriter() {342. return writer;343. }344.345. public User getUser() {346. return user;347. }348.349. // 客户端线程的构造方法350. public ClientThread(Socket socket) {351. try {352.this.socket = socket;353.reader = new BufferedReader(new InputStrea mReader(socket354. .getInputStream()));355.writer = new PrintWriter(socket.getOutputS tream());356. // 接收客户端的基本用户信息357. String inf = reader.readLine();358. StringTokenizer st = new StringTokenizer(i nf, "@");er = new User(st.nextToken(), st.nextTok en());360. // 反馈连接成功信息361. writer.println(user.getName() + user.getIp () + "与服务器连接成功!");362. writer.flush();363. // 反馈当前在线用户信息364. if (clients.size() > 0) {365. String temp = "";366. for (int i = clients.size() - 1; i >= 0; i--) {367. temp += (clients.get(i).getUser().getName() + "/" + clients368. .get(i).getUser().getIp())369. + "@";370. }371. writer.println("USERLIST@" + clients.s ize() + "@" + temp);372. writer.flush();373. }374. // 向所有在线用户发送该用户上线命令375. for (int i = clients.size() - 1; i >= 0; i --) {376. clients.get(i).getWriter().println( 377. "ADD@" + user.getName() + user .getIp());378. clients.get(i).getWriter().flush(); 379. }380. } catch (IOException e) {381. e.printStackTrace();382. }383. }384.385. @SuppressWarnings("deprecation")386. public void run() {// 不断接收客户端的消息,进行处理。

相关文档
最新文档