一、功能介绍

该功能实现了一个类似QQ的最简单多人聊天室,如下图所示。

二、目录结构

三、服务端

1)SocketServer类,该类是服务端的主类,主要负责创建聊天窗口,创建监听客户端的线程:

package multiThreadChatSocketServer;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class SocketServer {
private TextArea ta;
private TextField tf; private ServerSocket ss;
private Socket s;
private DataInputStream dis;
private DataOutputStream dos; public TextField getTextField() {
return tf;
} public TextArea getTextArea() {
return ta;
} public DataInputStream getDataInputStream() {
return dis;
} public DataOutputStream getDataOutputStream() {
return dos;
} public static void main(String[] args) {
SocketServer socketServer = new SocketServer();
socketServer.createUI();
socketServer.connect();
socketServer.createThread();
} public void close() {
try {
dis.close();
dos.close();
s.close();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 创建界面
*/
private void createUI(){
Frame f=new Frame("socketServer");
ta = new TextArea();
tf = new TextField();
Button send = new Button("send"); Panel p = new Panel();
p.setLayout(new BorderLayout());
p.add(tf, "Center");
p.add(send, "East"); f.add(ta, "Center");
f.add(p, "South"); MyServerListener listener = new MyServerListener(this);
//不管点击发送按钮还是输入框回车,都会触发listener事件
send.addActionListener(listener);
tf.addActionListener(listener);
//当关闭窗口的时候,退出系统
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setSize(400,400);
f.setVisible(true);
} /**
* 创建连接
*/
public void connect(){
try {
ss=new ServerSocket(8888);
s=ss.accept();
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 启动监听客户端发来的消息的线程
*/
public void createThread() {
MyServerReader reader = new MyServerReader(this);
reader.start();
}
}

2)MyServerReader类,该类实时监听客户端输入的信息,如果对方输入“bye”,则退出监听并关闭窗口

package multiThreadChatSocketServer;

import java.awt.TextArea;
import java.io.DataInputStream;
import java.io.IOException; /**
* 监听客户端发过来的消息,关显示在服务端的界面上
* @author Administrator
*
*/
class MyServerReader extends Thread {
private SocketServer server;
public MyServerReader(SocketServer server) {
this.server = server;
}
public void run() {
String info;
DataInputStream dis = server.getDataInputStream();
TextArea ta = server.getTextArea();
try {
while (true) {
info = dis.readUTF();
ta.append("对方说: " + info + "\n");
if (info.equals("bye")) {
server.close();
System.exit(0);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

3)MyServerListener类,是点发送按钮的时候执行的类

package multiThreadChatSocketServer;

import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException; /**
* 当点击发服务端的送按钮的时候,将信息显示在服务端的界面上,并将信息发送给客户端
* @author Administrator
*
*/
class MyServerListener implements ActionListener {
private SocketServer server; public MyServerListener(SocketServer server) {
this.server = server;
} public void actionPerformed(ActionEvent e) {
TextField tf = server.getTextField();
String info = tf.getText();
server.getTextArea().append("自己说: " + info + "\n");
try {
// writeUTF(value:String) :将 UTF-8 字符串写入字节流。先写入以字节表示的 UTF-8 字符串长度(作为 16 位整数),然后写入表示字符串字符的字节。
// 因为先把字符长度写入二进制,16位能保存的字节长度为65535,超出这个长度会报RangeError。
// writeUTFBytes(value:String):不添加字节长度直接写入字符串的字节数据。因此在读取的时候需要指定字节长度
server.getDataOutputStream().writeUTF(info);
} catch (IOException e1) {
e1.printStackTrace();
}
if (info.equals("bye")) {
server.close();
System.exit(0);
}
tf.setText("");
tf.requestFocus();
}
}

四、客户端

1)SocketClient类

package multiThreadChatSocketClient;

import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket; public class SocketClient {
private TextArea ta;
private TextField tf; private Socket s;
private DataInputStream dis;
private DataOutputStream dos; public TextField getTextField() {
return tf;
} public TextArea getTextArea() {
return ta;
} public DataInputStream getDataInputStream() {
return dis;
} public DataOutputStream getDataOutputStream() {
return dos;
} public static void main(String[] args) {
SocketClient socketClient = new SocketClient();
socketClient.createUI();
socketClient.connect();
socketClient.createThread();
} public void close() {
try {
dis.close();
dos.close();
s.close();
} catch (IOException e) {
e.printStackTrace();
}
} /**
* 创建界面
*/
private void createUI(){
Frame f=new Frame("socketClient");
ta = new TextArea();
tf = new TextField();
Button send = new Button("send"); Panel p = new Panel();
p.setLayout(new BorderLayout());
p.add(tf, "Center");
p.add(send, "East"); f.add(ta, "Center");
f.add(p, "South"); MyClientListener listener = new MyClientListener(this);
//不管点击发送按钮还是输入框回车,都会触发listener事件
send.addActionListener(listener);
tf.addActionListener(listener);
//当关闭窗口的时候,退出系统
f.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
f.setSize(400,400);
f.setVisible(true);
} /**
* 创建连接
*/
public void connect(){
try {
s = new Socket("127.0.0.1", 8888);
dis=new DataInputStream(s.getInputStream());
dos=new DataOutputStream(s.getOutputStream());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/**
* 启动监听服务端发来的消息的线程
*/
public void createThread() {
MyClientReader reader = new MyClientReader(this);
reader.start();
}
}

2)MyClientReader类

package multiThreadChatSocketClient;

import java.awt.TextArea;
import java.io.DataInputStream;
import java.io.IOException; /**
* 监听服务端发过来的消息,关显示在客户端的界面上
* @author Administrator
*
*/
class MyClientReader extends Thread {
private SocketClient client;
public MyClientReader(SocketClient client) {
this.client = client;
}
public void run() {
String info;
DataInputStream dis = client.getDataInputStream();
TextArea ta = client.getTextArea();
try {
while (true) {
info = dis.readUTF();
ta.append("对方说: " + info + "\n");
if (info.equals("bye")) {
client.close();
System.exit(0);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}

3)MyClientListener类

package multiThreadChatSocketClient;

import java.awt.TextField;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException; /**
* 当点击客户端的发送按钮的时候,将信息显示在客户端的界面上,并将信息发送给服务端
* @author Administrator
*
*/
class MyClientListener implements ActionListener {
private SocketClient client; public MyClientListener(SocketClient client) {
this.client = client;
} public void actionPerformed(ActionEvent e) {
TextField tf = client.getTextField();
String info = tf.getText();
client.getTextArea().append("自己说: " + info + "\n");
try {
client.getDataOutputStream().writeUTF(info);
} catch (IOException e1) {
e1.printStackTrace();
}
if (info.equals("bye")) {
client.close();
System.exit(0);
}
tf.setText("");
tf.requestFocus();
}
}

java socket之多人聊天室Demo的更多相关文章

  1. 多线程+socket实现多人聊天室

    最近在学习多线程的时候打算做一个简单的多线程socke聊天的程序,结果发现网上的代码都没有完整的实现功能,所以自己实现了一个demo: demo功能大致就是,有一个服务端负责信息转发,多个客户端发送消 ...

  2. 基于Socket实现多人聊天室

    当前支持: 1.仅文字 2.加入聊天室提醒 3.退出聊天室提醒 可能出现的BUG: 1.可能出现客户端发送信息后不能及时推送,需要下一个客户端发送信息后一起推送 服务端代码: 1 package co ...

  3. 66 网络编程(五)——TCP多线程实现多人聊天室

    思路 客户端读写各一个类,可以使内部类,实现Runnable.读写类都与服务器端建立连接,一个收,一个发. 客户端实现接收和转发.多线程实现每个客户端的连接(使与各客户端的连接独立). 服务器端中创建 ...

  4. 与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室

    原文:与众不同 windows phone (31) - Communication(通信)之基于 Socket UDP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  5. 与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室

    原文:与众不同 windows phone (30) - Communication(通信)之基于 Socket TCP 开发一个多人聊天室 [索引页][源码下载] 与众不同 windows phon ...

  6. 多人聊天室(Java)

    第1部分 TCP和UDP TCP:是一种可靠地传输协议,是把消息按一个个小包传递并确认消息接收成功和正确才发送下一个包,速度相对于UDP慢,但是信息准确安全:常用于一般不要求速度和需要准确发送消息的场 ...

  7. java小程序---简陋版多人聊天室

    功能需求: 1 每运行一次主函数,创建一个客户端聊天界面; 2 客户端界面分三块,公屏(显示所有客户端发送的信息),私屏(用于输入个人想要发送的信息),发送按钮(点击一次,将客户端信息发送到服务端) ...

  8. java swing+socket实现多人聊天程序

    swing+socket实现多人聊天程序 1.准备工作 先看效果: 客户端项目结构图: 服务端项目结构图: 2.运行原理 服务端 先开一个线程serverListerner,线程中开启一个Server ...

  9. Socket.io官方聊天室DEMO的学习笔记

    照着Socket.io官方的聊天室代码敲了一遍,遇到了一个奇怪的问题: 每次点击SEND按钮的时候,都会重新刷新页面. 在点击页面的一瞬间,看到了正在加载jquery的提示, 然后以为是jquery用 ...

随机推荐

  1. JAVA EXAM2 复习提纲

    [真假分数相加] //inheritence, extends, use this & super 子类的方法 //two constructors, non-default use 'thi ...

  2. cocoapods 更新本地仓库 pod setup/update 无限远程中断

    升级 cocoapods 无限远程中断:网络不好 试了很多解决方法: 1.替换源,2.设置下载速度,3.清空本地master仓库,4.删了本地的pod库,5.半夜3-5点更新,6.按照失败提示的 (p ...

  3. java 线程Thread 技术--方法演示生产与消费模式

    利用wait 与notifyAll 方法进行演示生产与消费的模式的演示,我们两个线程负责生产,两个线程消费,只有生产了才能消费: 在effective Java 中有说过: 1. 在Java 中 ,使 ...

  4. HTML基础学习笔记(1)

    HTML学习笔记(1) 1.常用快捷键 win+d---返回桌面 win+e---我的电脑 win+r---打开运行 Alt+tab---切换软件 ctrl+tab---切换软件文档 F2---重命名 ...

  5. jenkins如何获取text parameter多行的文本内容

    如果是string的插件 可以直接获取 但text的不可以 如果用 echo %aaa% 这种方式进行打印的话 会发现只打印了第一行 最后的解决方案: 使用了python脚本 在python脚本里通过 ...

  6. Repeater绑定数组

    前台代码: <asp:Repeater ID="rptarry" runat="server" >         <HeaderTempla ...

  7. Linux用7zip解压缩分卷文件

    背景:在服务器迁移过程中,有大量非结构化文件(主要是office文档和图片),目录结构太大,高达80-100G,传输耗时且容易受网络 等其他原因意外中断,以致于传输失败,于是采用分卷压缩,即使传输失败 ...

  8. C# Convert.ToInt32和int.Parse转换null和空字符串时的不同表现

    Convert.ToInt32最终调用的函数见下图: int.Parse调用的函数见下图: 具体的见https://www.cnblogs.com/leolis/p/3968943.html的博客,说 ...

  9. JavaScript DOM操作浅谈

    1.理解DOM: DOM(Document Object Model ,文档对象模型)一种独立于语言,用于操作xml,html文档的应用编程接口. 怎么说,我从两个角度理解: 对于JavaScript ...

  10. CentOS 7系统关闭yum自动下载更新

    安装CentOS 7后,系统yum自动更新状态默认为开启,若禁止系统自动更新需要手动关闭. 1.进入yum目录 [root@localhost ~]$ cd /etc/yum 2.编辑yum-cron ...