一、功能介绍

该功能实现了一个类似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. swift - 听云监测(Testin - Bugout) - 集成

    听云的SDK集成放的太难找了,官方demo到现在也没找到.. 我找了半天没找到在哪,看下面俩链接吧, 切记:添加的三方库 以文档为主,视频里的三方库 不一定正确 iOS SDK 集成:https:// ...

  2. shell条件控制和循环结构

    一.简介 Shell编程中循环命令用于特定条件下决定某些语句重复执行的控制方式,有三种常用的循环语句:for.while和until.while循环和for循环属于“当型循环”,而until属于“直到 ...

  3. JSON与GSON比较

    JSON: 是Android SDK官方的库,所以在开发移动端的工程时就必须使用JSON.进行数据的转换和处理 GSON: GSON适用于服务端,gson比json功能更加强大.比如在集合类的处理.自 ...

  4. Solidity语言基础 和 Etherum ERC20合约基础

    1. 类型只能从第一次赋值中推断出来,因此以下代码中的循环是无限的,  小. for (var i = 0; i < 2000; i++) { ... } --- Solidity Types ...

  5. python 常库介绍及安装方法

    bsddb3:BerkeleyDB的连接组件Cheetah-1.0:我比较喜欢这个版本的cheetahcherrypy:一个WEB frameworkctypes:用来调用动态链接库DBUtils:数 ...

  6. 关于Vector,map等迭代器问题

    vector.erase(it):后,it自动++,一定要弄清楚,删除成功后it指向删除的下一个地址. 对于map.erase(it),返回值为NULL,而Vector是返回itorator

  7. Oracle_SQL(7) 复杂查询

    1.rownum 伪列<,<=select * from emp where rownum<5; 取工资前3名的人员 select * from (select * from emp ...

  8. 公共的service接口

    package com.taotao.manager.service; import java.util.List; /** * @author Administrator * * @param &l ...

  9. Canvas绘图 (html5新增特性)

    Canvas 使用<canvas>对象,需要设置属性:width,height.指定绘图的区域大小.在canvas标签前后出现的信息将在不支持<canvas>元素的浏览器中显示 ...

  10. BZOJ 3932 [CQOI2015]任务查询系统 - 差分 + 主席树

    Solution 差分就好了, 在$s_i$ 的点+1, $e_i + 1$ 的点 - 1. 查询的时候注意$l == r$ 要返回 $k * b[l]$ ,而不是$sum[node] $因为当前位置 ...