-
2021-04-23 20:34:31
需求分析:
实现简单的群聊,需要用到Java的Socket(套接字)和ServerSocket(服务器端套接字)两个类。当客户端(Socket)发送信息到固定的服务器(ServerSocket)的地址和端口,会有服务器端监听到该信息,然后转发至每个用户,即聊天室。要想把信息转发到各个用户,需要把这所有的用户用一个集合(List)存起来,遍历集合内所有用户,进行发送。
其中难点在于如何使用多线程接受转发信息。对于服务器端,需要不断监听用户端的信息传输,每当监听到一个用户发来消息,会开辟一个线程对消息转发至各个用户。对于客户端,每创建一个用户,需要开辟一条线程,并且该用户需要接收和发送消息,接收和发送消息两者间是不同步的,又需要开辟两条线程,线程下面有线程。
代码如下:
1、服务器端
/**
服务器端,服务器创建入口
*/
public Server{
public static void main(String[] args){
//创建一个服务器,端口号为8000
ServerSocket server = new ServerSocket(8000);
//创建一个死循环,让服务器一直处于监听客户端信息的状态
while(true){
Socket socket = server.accept();
//传入监听到的socket,并且启动线程
ServerThread st = new SeverThread(socket);
Thread th = new Thread(st);
th.start();
//异常未处理
}
}
}
2、当监听到来自客户端的消息,开辟新的服务器用来接收
/**
服务器子线程端
*/
public ServerThread implements Runnable {
private static LinkedList list = new LinkedList<>();
private Socket socket;
public ServerSocket(Socket socket){
//把监听到的socket传过来
this.socket = socket;
//并且添加到集合中
list.add(socket);
}
@Override
public void run(){
//接收客户端发过来的消息(读)
//为了提高读写效率,把字节流用转换流转换为字符流
//然后用缓存流封装转换流
BufferedReader br = null;
try{
br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg = null;
while((msg = br.readLine()) != null){
sendAll(msg);
}
} catch(IOException e){
e.printStackTrace();
}
}
//发送给所有人
public void sendAll(String msg){
//遍历集合,然后发送给集合(群)里面的所有人
PrintStream ps = null;
for(Socket sk : list){
try{
ps = new PrintStream(sk.getOutputStream());
ps.println(msg);
ps,flush();
} catch(IOException e){
e.printStackTrace();
}
}
}
}
3、客户端,每个用户的入口,每当有用户进入,会开辟一条线程
public Client{
public static void main(String[] srgs){
ClientThread ct = new ClientThread();
Thread th = new Thread(ct);
th.start();
}
}
4、客户端子线程,每当接收和发送消息,会开辟线程用来同步
public ClientThread implements Runnable{
@Override
public run(){
Socket socket = null;
try {
//使用当前主机服务器,端口号设为8000
socket = new Socket("localhost", 8000);
Thread th_1 = new Thread(new ClientReceive(socket));
th_1.start();
Thread th_2 = new Thread(new ClientSend(socket));
th_2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
5、客户端发送信息子线程
public ClientSend implements Runnable{
private Socket socket;
public ClientSend(Socket socket){
this.socket = socket;
}
@Override
public void run(){
//发送信息
PrintStream ps = null;
Scanner input = new Scanner(System.in);
try {
while(ture) {
//输入发送的信息(写)
ps = new PrintStream(socket.getOutputStream());
String msg = input.next();
ps.println(msg);
ps.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
6、客户端接受信息子线程
public ClientReceive implements Runnable{
private Socket socket;
public ClientReceive(Socket socket){
this.socket = socket;
}
@Override
public void run(){
BufferedReader br = null;
String msg = null;
//接收信息(读)
try {
while(true) {
br = new BufferedReader(new InputStreamReader(socket.getInputStream));
while((msg = br.readLine()) != null) {
System.out.println(msg);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
更多相关内容 -
java聊天系统,有群聊功能
2019-12-19 14:54:44我们小组大二做的一个简单的聊天系统,分为服务器端和客户端,启动服务器端之后,客户端之间进行收发信息,还有群组聊天功能。完整的项目描述见压缩包内的报告和源码。使用mysql数据库,已导出为qq.sql文件。 解压... -
Java NIO实现简易群聊功能
2022-03-27 15:06:08服务端代码 开启ServerSocketChannel,设置为非阻塞,并...import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator;服务端代码
- 开启ServerSocketChannel,设置为非阻塞,并声明为全局变量
- 开启一个selector,并绑定客户端链接事件
- 启动监听方法,循环监听事件,阻塞监听事件
- 读取到客户端消息,并转发给其他客户端
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.*; import java.util.Iterator; public class GroupChatServer { private ServerSocketChannel serverSocketChannel; private Selector selector; private static final int PORT = 6666; public GroupChatServer() { try { serverSocketChannel = ServerSocketChannel.open(); serverSocketChannel.configureBlocking(false); serverSocketChannel.socket().bind(new InetSocketAddress(PORT)); selector = Selector.open(); serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT); System.out.println("服务端已启动"); } catch (Exception e) { e.printStackTrace(); } } public void listen() { try { while (true) { int count = selector.select(); if (count == 0) { continue; } Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isAcceptable()) { SocketChannel socketChannel = serverSocketChannel.accept(); socketChannel.configureBlocking(false); socketChannel.register(selector, SelectionKey.OP_READ); System.out.println(socketChannel.getRemoteAddress() + "上线了"); } if (key.isReadable()) { //处理数据读取 readData(key); } keyIterator.remove(); } } } catch (Exception e) { } finally { } } private void readData(SelectionKey key) { SocketChannel channel = null; try { channel = (SocketChannel) key.channel(); ByteBuffer byteBuffer = ByteBuffer.allocate(1024); int read = channel.read(byteBuffer); if (read > 0) { //输出读取到的数据 String msg = new String(byteBuffer.array(), 0, read); System.out.println("转发客户端消息:" + msg); //向其他客户端转发消息 sendMsgToOther(msg, channel); } } catch (IOException e) { try { System.out.println(channel.getRemoteAddress() + " 已下线"); //取消注册事件,并关闭通道 key.cancel(); channel.close(); } catch (IOException ex) { ex.printStackTrace(); } } } private void sendMsgToOther(String msg, SocketChannel self) { selector.keys().forEach(key -> { SelectableChannel channel = key.channel(); if (channel instanceof SocketChannel && channel != self) { //发给所有除自己意外的客户端 SocketChannel socketChannel = (SocketChannel) channel; ByteBuffer src = ByteBuffer.wrap(msg.getBytes()); try { socketChannel.write(src); } catch (IOException e) { e.printStackTrace(); } } }); } public static void main(String[] args) { GroupChatServer server = new GroupChatServer(); server.listen(); } }
客户端代码
- 链接到服务器端,得到SocketChannel,并设置为非阻塞
- 开启一个selector,并绑定read事件
- 启动一个线程,每隔3秒,读取从服务器端发送过来的数据
- 开启一个Scanner,通过控制台发送信息给服务端
import java.io.IOException; import java.net.InetSocketAddress; import java.nio.ByteBuffer; import java.nio.channels.SelectionKey; import java.nio.channels.Selector; import java.nio.channels.SocketChannel; import java.util.Iterator; import java.util.Scanner; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class GroupChatClient { private static final String SERVER = "127.0.0.1"; private static final int PORT = 6666; private SocketChannel channel; private Selector selector; private String userName; public GroupChatClient() throws IOException { //链接到服务器 channel = SocketChannel.open(new InetSocketAddress(SERVER, PORT)); //设置为非阻塞 channel.configureBlocking(false); selector = Selector.open(); //绑定read事件到selector channel.register(selector, SelectionKey.OP_READ); userName = channel.getLocalAddress().toString(); System.out.println(userName + " 我已上线"); } public void sendInfo(String msg) { msg = userName + "说:" + msg; try { channel.write(ByteBuffer.wrap(msg.getBytes())); } catch (IOException e) { e.printStackTrace(); } } public void readInfo() { try { //线程阻塞,等待消息 int count = selector.select(); if (count > 0) { Iterator<SelectionKey> keyIterator = selector.selectedKeys().iterator(); while (keyIterator.hasNext()) { SelectionKey key = keyIterator.next(); if (key.isReadable()) { SocketChannel channel = (SocketChannel) key.channel(); //得到一个ByteBuffer ByteBuffer byteBuffer = ByteBuffer.allocate(1024); //读取数据到Buffer int read = channel.read(byteBuffer); System.out.println(new String(byteBuffer.array(), 0, read)); } //移除已处理的key keyIterator.remove(); } } } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws IOException { GroupChatClient groupChatClient = new GroupChatClient(); //启动一个线程,每隔3秒,读取从服务器端发送过来的数据 ExecutorService executor = Executors.newSingleThreadExecutor(); executor.submit(() -> { while (true) { groupChatClient.readInfo(); Thread.sleep(3000l); } }); //发送数据给服务端 Scanner scanner = new Scanner(System.in); while (scanner.hasNextLine()) { String str = scanner.nextLine(); groupChatClient.sendInfo(str); } } }
测试
1)启动服务端
2)启动3个客户端服务端控制台
服务端已启动 /127.0.0.1:57806上线了 /127.0.0.1:57814上线了 /127.0.0.1:57825上线了 转发客户端消息:/127.0.0.1:57825说:我是01 转发客户端消息:/127.0.0.1:57814说:我是02 转发客户端消息:/127.0.0.1:57806说:我是03 /127.0.0.1:57825 已下线 /127.0.0.1:57814 已下线 /127.0.0.1:57806 已下线
客户端控制台
/127.0.0.1:57825 我已上线 我是01 /127.0.0.1:57814说:我是02 /127.0.0.1:57806说:我是03
/127.0.0.1:57814 我已上线 /127.0.0.1:57825说:我是01 我是02 /127.0.0.1:57806说:我是03
/127.0.0.1:57806 我已上线 /127.0.0.1:57825说:我是01 /127.0.0.1:57814说:我是02 我是03
-
java的容易群聊实现
2021-04-23 20:33:32import java.io.IOException;import java.net.ServerSocket;import java.net.Socket;/*** 创建调用服务器线程的主类* @author Administrator**/public class ThreadMain {/*** @param args*/public stat...服务器总类:
package GroupChat;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
/**
* 创建调用服务器线程的主类
* @author Administrator
*
*/
public class ThreadMain {
/**
* @param args
*/
public static void main(String[] args) {
ThreadMain tm=new ThreadMain();
tm.StrSer(1234);
}
public void StrSer(int port){
try {
ServerSocket ss=new ServerSocket(port);
System.out.println("服务器创建成功");
while(true){
Socket client=ss.accept();
System.out.println("客户机连接");
ServerThread st=new ServerThread(client);
st.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
服务器单个线程类:
package GroupChat;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
/**
* 创建服务器线程类,该类继承自Thread
* @author Administrator
*
*/
public class ServerThread extends Thread{
private Socket client;//服务器连接对象
private OutputStream out;//输出流对象
private InputStream in;//输入流对象
public User use=new User();
/**
* 构造方法,传入该线程要处理的连接对象
* @param lient:要处理的连接对象
*/
public ServerThread(Socket client){
this.client=client;
}
/**
* 重写线程的Run方法
*/
public void run(){
//处理连接的方法
ProcessChat();
}
/**
* 处理连接的方法
*/
private void ProcessChat() {
try {
out=client.getOutputStream();//获得相应的输出流对象
in=client.getInputStream();//获得相应的输入流对象
BufferedReader br=new BufferedReader(new InputStreamReader(in));//实例化缓冲读取信息的对象
SendMsg("欢迎来到服务器\n请输入用户名:");
use.name=br.readLine();
SendMsg("请输入密码:");
use.pew=br.readLine();
boolean bool=DOT.Checkuse(use);//检验用户信息
if(!bool){
client.close();//如果检查不通过就关闭
return;
}
ChatTool.AddThread(this);//添加线程
use.logintime=System.currentTimeMillis();
use.adress=client.getRemoteSocketAddress().toString();
String str="";
str=br.readLine();
//当str为空时,也要退出。处理强行关闭客户机
while(!"bye".equals(str)&&str!=null){
System.out.println(use.name+":"+str);
ChatTool.SendAll(use, str);
str=br.readLine();
}
out.write(str.getBytes());
ChatTool.DeleThread(this);
client.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 向客户机发送信息的方法
* @param string:要发送的信息
*/
public void SendMsg(String str) {
str=str+"\r\n";
try {
out.write(str.getBytes());
out.flush();//强制输出
} catch (IOException e) {
e.printStackTrace();
}
}
}
用户验证类(预加载好了几个用户):
package GroupChat;
import java.util.HashMap;
import java.util.Map;
/**
* 创建验证用户信息的类,用来验证用户信息
* @author Administrator
*
*/
public class DOT {
private static Map map=new HashMap();
/**
* 创建验证用户信息的方法
* @param use:要验证的用户
* @return:是否成功
*/
public static boolean Checkuse(User use){
if(use.pew.equals(map.get(use.name))){
return true;//验证成功就返回True
}
return false;
}
static{
for(int i=0;i<5;i++){
User use=new User();
use.name="name"+i;
use.pew="pew"+i;
map.put(use.name,use.pew);//放入map中
}
}
}
存装静态方法:
package GroupChat;
import java.util.HashMap;
import java.util.Map;
/**
* 创建验证用户信息的类,用来验证用户信息
* @author Administrator
*
*/
public class DOT {
private static Map map=new HashMap();
/**
* 创建验证用户信息的方法
* @param use:要验证的用户
* @return:是否成功
*/
public static boolean Checkuse(User use){
if(use.pew.equals(map.get(use.name))){
return true;//验证成功就返回True
}
return false;
}
static{
for(int i=0;i<5;i++){
User use=new User();
use.name="name"+i;
use.pew="pew"+i;
map.put(use.name,use.pew);//放入map中
}
}
}
用户类:
package GroupChat;
/**
* 创建用户信息类,用来存放用户信息
* @author Administrator
*
*/
public class User {
public String name;//用户名字
public String pew;//用户密码
public long logintime;//用户的上线时间
public String adress;//用户的地址
}
-
java swing实现群聊功能
2018-07-11 16:18:50群聊功能。使用java swing,socket,多线程实现。 1) 客户端用来接收和展示数据,服务器实现与底层数据的交互。 2) 实现服务器端与客户端的分离,如果要操作数据库,可以在服务器端改代码调用Model。 3) 实现用户... -
javaWeb(四个范围)实现聊天室功能(群聊+私聊)
2017-08-12 01:54:06主要用servlet+jsp+Qracle实现聊天室的私聊+群聊功能,灵活运用了javaWeb的四个范围实现私聊 -
java实现小型局域网群聊功能(C/S模式)
2020-09-01 18:51:00主要介绍了java利用TCP协议实现小型局域网群聊功能(C/S模式) ,感兴趣的小伙伴们可以参考一下 -
一键登录,实现群聊、私聊功能的java聊天室
2020-11-10 11:00:11java聊天室,采用BIO通信方式,支持群聊天,私聊功能,GUI界面,一键登录.。 -
Java聊天室(实现群聊、私聊功能)GUI界面
2020-09-22 19:51:05一对多群聊。 1、先启动服务端,等待客户端连接…。 2、启动三个客户端,代表不同的用户。右上角分别选择不同的用户进行登录。 3、登录的用户可对所有用户发送消息,也可以对某个用户发送消息。 下面是具体的...不说废话,先看效果,目前实现的基本功能有一对一私聊。一对多群聊。
1、先启动服务端,等待客户端连接…。
2、启动三个客户端,代表不同的用户。右上角分别选择不同的用户进行登录。
3、登录的用户可对所有用户发送消息,也可以对某个用户发送消息。
下面是具体的代码实现(采用传统的BIO实现,也可参考我另一篇博客NIO实现其中的功能)。
server端代码:package Server; import java.io.*; import java.net.*; import java.util.*; /* server端 */ public class ChatServer { private ServerSocket ss; private boolean flag = false; private Map<String, Client> clients = new HashMap<>(); public static void main(String args[]) { new ChatServer().start(); } public void start() { try { ss = new ServerSocket(8888); flag = true; System.out.println("Server启动成功..."); } catch (BindException e) { System.out.println("端口使用中!!!"); } catch (IOException e) { e.printStackTrace(); } try { //接收客户端的连接 while (flag) { //accept方法是一个阻塞的方法,会阻塞当前的线程。 Socket socket = ss.accept(); Client c = new Client(socket); System.out.println("一个客户端已经连接..."); new Thread(c).start(); } } catch (IOException e) { System.out.println("Client closed..."); } finally { try { if (ss != null) ss.close(); } catch (IOException e) { e.printStackTrace(); } } } private class Client implements Runnable { private Socket s; private String userName = ""; private DataInputStream input = null; private DataOutputStream output = null; private boolean connected = false; private BufferedOutputStream fout = null; private String saveFilePath = ""; public Client(Socket s) { this.s = s; try { input = new DataInputStream(s.getInputStream()); output = new DataOutputStream(s.getOutputStream()); connected = true; } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { byte buffer[] = new byte[1024]; int len = 0; try { while (connected) { String msg[] = input.readUTF().split("#");//msg={" ","登录用户","目标用户","要发送的信息"} switch (msg[0]) { case "LOGIN": String userName = msg[1]; if (clients.containsKey(userName)) { output.writeUTF("FAIL");//已经登录 System.out.println("拒绝了一个重复连接..."); closeConnect(); } else { output.writeUTF("SUCCESS"); clients.put(userName, this); //将所有登录用户信息发送给新登录的用户 StringBuffer allUsers = new StringBuffer(); allUsers.append("ALLUSERS#"); for (String user : clients.keySet()) allUsers.append(user + "#"); output.writeUTF(allUsers.toString()); //将新登录的用户信息发送给其他用户 String newLogin = "LOGIN#" + userName; sendMsg(userName, newLogin); this.userName = userName; } break; case "LOGOUT": clients.remove(this.userName); String logoutMsg = "LOGOUT#" + this.userName; sendMsg(this.userName, logoutMsg); System.out.println("用户" + this.userName + "已下线..."); closeConnect(); break; case "SENDONE": Client c = clients.get(msg[1]);//获取目标用户的连接 String msgToOne=""; if (c != null) { msgToOne="SENDONE#" + this.userName + "#" + msg[2]; c.output.writeUTF(msgToOne); c.output.flush(); } break; case "SENDALL": String msgToAll = ""; msgToAll = "SENDALL#" + this.userName + "#" + msg[1]; sendMsg(this.userName, msgToAll); break; } } } catch (IOException e) { System.out.println("Client closed..."); connected = false; } finally { try { if (input != null) input.close(); if (output != null) output.close(); if (fout != null) fout.close(); if (s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } } public void closeConnect() { connected = false; try { if (input != null) input.close(); if (output != null) output.close(); if (s != null) s.close(); } catch (IOException e) { e.printStackTrace(); } } public void sendMsg(String fromUser, String msg) { String tempUser = ""; try { for (String toUser : clients.keySet()) { if (!toUser.equals(fromUser)) { tempUser = toUser; DataOutputStream out = clients.get(toUser).output; out.writeUTF(msg); out.flush(); } } } catch (IOException e) { System.out.println("用户" + tempUser + "已经离线!!!"); } } } }
客户client端:
package Client; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.io.*; import java.net.Socket; import java.net.SocketException; /* 客户client端 */ public class ChatClient extends JFrame { private JTextArea sendArea, contentArea; JPanel p1, p11, p12, p2, p21, p22; JComboBox<String> user1, user2; private RecvThread clientThread = null; private String filePath = null; public void start() { Container con = getContentPane(); con.setLayout(new BorderLayout()); Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); int screenWidth = screenSize.width / 2; int screenHeight = screenSize.height / 2; int height = getHeight(); int width = getWidth(); setSize(350, 400); setLocation((screenWidth - width) / 2, (screenHeight - height) / 2); sendArea = new JTextArea(3, 10);//设置发送区域几行几列 sendArea.setBorder(BorderFactory.createLineBorder(Color.BLUE, 1)); sendArea.setLineWrap(true); sendArea.setWrapStyleWord(true);//激活断行不断字功能 sendArea.addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { if ('\n' == e.getKeyCode()) if (clientThread != null) { clientThread.sendMsg(); } } }); contentArea = new JTextArea(6, 10); contentArea.setBorder(BorderFactory.createLineBorder(Color.BLUE, 1)); //北边接收消息区域 p1 = new JPanel(); p1.setLayout(new BorderLayout()); p11 = new JPanel(); p11.setLayout(new GridLayout(1, 2)); JLabel l1 = new JLabel("选择你的身份:"); user1 = new JComboBox<>(); user1.addItem("-----选择-----"); user1.addItem("张三"); user1.addItem("李四"); user1.addItem("王五"); user1.addItem("小六"); user1.addItemListener(e -> { if (e.getStateChange() == ItemEvent.SELECTED) { // System.out.println("选中的项:" + user1.getSelectedItem()); if (user1.getSelectedIndex() == 0) { return; } clientThread = new RecvThread((String) user1.getSelectedItem()); new Thread(clientThread).start(); } }); p11.add(l1); p11.add(user1); p12 = new JPanel(); p12.setLayout(new GridLayout(1, 1)); p12.add(new JScrollPane(contentArea)); p1.add(p11, BorderLayout.NORTH); p1.add(p12, BorderLayout.SOUTH); //南边发送消息区域 p2 = new JPanel(); p2.setLayout(new BorderLayout()); p21 = new JPanel(); p21.setLayout(new GridLayout(2, 2)); user2 = new JComboBox<>(); user2.addItem("所有用户"); JLabel l2 = new JLabel("选择要发送的用户:"); p21.add(l2); p21.add(user2); p22 = new JPanel(); p22.setLayout(new GridLayout(1, 1)); p22.add(new JScrollPane(sendArea)); p2.add(p21, BorderLayout.NORTH); p2.add(p22, BorderLayout.SOUTH); con.add(p1, BorderLayout.NORTH); con.add(p2, BorderLayout.SOUTH); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { if (clientThread != null) clientThread.exit(); System.exit(0); } }); } private class RecvThread implements Runnable { private Socket s = null; private DataInputStream in = null; private DataOutputStream out = null; private String userName; private boolean isLogin = false; StringBuilder msg = new StringBuilder(); public RecvThread(String userName) { this.userName = userName; } //用户登录 public void login() { try { s = new Socket("127.0.0.1", 8888);//监听本机的8888端口 in = new DataInputStream(s.getInputStream()); out = new DataOutputStream(s.getOutputStream()); String sendMsg = "LOGIN#" + userName; out.writeUTF(sendMsg); out.flush(); //服务器返回的信息 String recv = in.readUTF(); if (recv.equals("FAIL")) { showMsg(userName + "已经登录!!!"); user1.setEnabled(true); exit(); return; } else if (recv.equals("SUCCESS")) { showMsg("登录成功!!!"); user1.setEnabled(false); isLogin = true; } } catch (IOException e) { e.printStackTrace(); } } public void exit() {//用户退出,释放资源 try { if (isLogin) { out.writeUTF("LOGOUT"); out.flush(); isLogin = false; } if (in != null) in.close(); if (out != null) out.close(); if (s != null) s.close(); } catch (IOException e) { System.out.println("连接已关闭!!!"); } } //用户发送消息 public void sendMsg() { int len = 0; // String fileName = ""; if (!isLogin) { showMsg("没有登录,请登录!!!"); return; } msg.setLength(0); String sendInfo = sendArea.getText().trim(); String user = (String) user2.getSelectedItem(); if(sendInfo.equals("")) sendInfo=" "; try { if (user.equals("所有用户")) {//给所有用户发送消息 msg.append("SENDALL#"); msg.append(sendInfo); } else {//只给某个用户发送消息 msg.append("SENDONE#"); msg.append(user+"#" + sendInfo);//如果这里sendinfo=SENDFILE那么可能就会发生错误。有待改进.... } out.writeUTF(msg.toString()); showMsg("我说:" + sendInfo); sendArea.setText(""); } catch (IOException e) { e.printStackTrace(); } } @Override public void run() { login(); try { while (isLogin) { String msgs[] = in.readUTF().split("#"); switch (msgs[0]) { case "LOGIN": user2.addItem(msgs[1]);//后面可以加个提示信息 break; case "ALLUSERS": for (int i = 1; i < msgs.length; i++) { if (!"".equals(msgs[i])) user2.addItem(msgs[i]); } break; case "SENDONE": showMsg(msgs[1] + ":" + msgs[2]); break; case "SENDALL": showMsg(msgs[1] + "对所有人说:" + msgs[2]); break; case "LOGOUT": showMsg("用户" + msgs[1] + "已下线!!!"); user2.removeItem(msgs[1]); break; } } } catch (SocketException e) { System.out.println(userName + "已退出..."); } catch (IOException e) { isLogin = false;//返回数据出现异常,退出登录 e.printStackTrace(); } } } //设置显示信息 public void showMsg(String msg) { contentArea.append(msg + "\n"); contentArea.setCaretPosition(contentArea.getText().length());// 自动滚动到文本区的最后一行 } public static void main(String args[]) { //将swing风格控件渲染成Windows风格 try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception e) { e.printStackTrace(); } new ChatClient().start(); } }
上面代码我都放在gitte上面,需要的自己去拿聊天室源代码
-
java聊天室群聊及私聊实现!
2019-03-16 21:52:12java聊天室群聊及私聊实现! 一:业务逻辑 连接数据库,实现注册登录账号的功能 使用serverSocket接收并发送消息实现服务器功能 客户端使用socket与服务器交互 二:类设计及代码结构 MyMessage类:该类主要用于... -
当年的聊天室,今天的我(java实现聊天室群聊功能)
2021-01-11 02:23:54预备小知识连接: 小小聊天室,慢慢的回忆啊!(TCP 通信实现) 先看效果 主要可以分为三个层:服务端层,客户端...import java.io.Closeable; import java.io.IOException; /** * 用于关闭的工具类 * */ publ -
Java做的Swing聊天程序,支持私聊/群聊/踢人
2021-04-16 18:00:173.多用户之间的群组聊天(群聊) 4.用户与用户之间的聊天(私聊),也称为悄悄话 5.聊天内容实时自动更新 6.管理员对非法用户的踢人功能。 7.保存聊天记录 8.清除聊天记录 9.程序各种情况的业务校验 10.人性化的提示 -
Java实现简单的QQ群聊系统
2021-01-19 19:22:29利用Java实现的一个简单的群聊程序,模仿群聊,通过本地通讯,实现了简单的群聊功能,目的是为了熟悉Java的Socket、线程、输入/输出流、Swing以及利用javadoc生成HTML文档。练习时候写的,所以功能和界面都比较简单... -
websocket实现群聊
2021-05-23 20:51:48websocket实现群聊一、Server层代码层次图DL.javaWSServer.javaHelloServlet.java二、主页index.html三、实现效果图: 一、Server层 代码层次图 注意:端口号要一致9090 DL.java public class DL { /** * 私有的... -
Java聊天室—-多线程实现群聊、私聊、系统消息 (服务端完整代码奉上)
2020-12-22 13:26:39是不是试了很多次都没有达到自己想要的效果呢? 没关系,看到这你就已经有收获了 文章目录一、动图效果展示二、服务端代码(核心)三、bug吐槽四、分享交流 一、动图效果展示 ...import java.util.conc -
Java-->实现群聊功能(C/S模式--TCP协议)
2021-02-12 10:40:01packagecom.dragon.java.tcpchat;importjava.io.BufferedReader;importjava.io.IOException;importjava.io.InputStreamReader;importjava.io.PrintStream;importjava.net.InetAddress;importjava.net.Socket;importj... -
Java实现通过服务器实现客户端之间的简单群聊
2021-03-22 17:53:13其功能模型如下: 运行截图:1、需要先启动服务器端,界面如下: 2、启动2或2个以上个客户端(名字随机): 3、聊天结果: 代码部分:服务器端代码实现:package pack2;import java.net.*;import java... -
java网络编程 socket通信实现群聊私聊功能
2021-12-28 14:28:12java网络编程 socket通信实现多人聊天,群聊,私聊功能 -
Java 实现群消息聊天
2021-08-20 11:37:32Java 实现群消息聊天 -
java Socket实现多人群聊与私聊功能
2020-08-27 04:12:19主要为大家详细介绍了java Socket实现多人群聊与私聊功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下 -
java聊天器(已实现私聊和群聊等功能).zip
2021-06-27 19:48:41适合课设参考哦 -
java实现群聊功能
2011-03-29 00:10:36java语言实现群聊系统的啦,绝对能用,放心。。。。。。。。 -
JAVA Netty实现聊天室+私聊功能的示例代码
2020-08-24 20:41:44主要介绍了JAVA Netty实现聊天室+私聊功能的示例代码,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧 -
Java网络编程:TCP实现群聊功能代码
2020-03-15 21:29:35Java网络编程:TCP实现群聊功能代码 实现的功能:群聊 具体操作流程的大致思路: 某个客户端发送消息,服务器将该消息转发给其余客户端(除了自己)。 代码一共分两个端(服务器和客户端(其中客户端一共3个代码))... -
Java 实现局域网聊天室功能(私聊,群聊)
2022-03-17 16:09:57Java 实现局域网聊天室功能(私聊,群聊) -
Java中用网络通信实现聊天室私聊和群聊的功能
2021-10-15 23:44:40Java中用网络通信实现聊天室私聊和群聊的功能客户端代码(Client):服务端代码(Server): 客户端代码(Client): package homework10.homework1015; import java.io.BufferedReader; import java.io.IOException; ... -
Java网络编程,模拟QQ群聊功能
2020-07-01 18:16:23Java网络编程,模拟QQ群聊功能 一、网络编程知识点简介: 1.C/S架构:Client客户端/Server服务器: 涉及到的应用:桌面的应用软件,QQ,王者荣耀 涉及到的技术:Socket网络编程 2.网络: 各个孤立的工作站或主机相连在... -
java 实现群聊私聊功能(网络编程+io流) 封装终极版
2020-01-12 20:33:02首先明确一下目的:实现一个服务端加多个客户端可用,带有群聊和私聊功能的小项目(通过控制台输入); 服务端 服务端起到了转发的作用,一个client通过发送消息给服务端,服务端接受到消息之后判断是要群发还是私发... -
基于WebSocket实现一个简易的群聊功能
2022-04-18 20:38:12本文主要来讲解如何使用WebSocket来实现一个简易的群聊功能 引入maven依赖 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</...