首先说明的是,本帖中的例子是来自网上的一个例子,经过了优化后的结果
实现以下功能:
1.在服务端提示所有客户端发来的消息以及当前的在线人数
2.服务端自动转发新上线用户的IP端口号消息给所有用户(当前用户除外)
3.服务端自动转发当前客户发给其他客户的消息
4.服务端自动转发离线客户的消息
5.服务端接收客户端的断开连接消息,可以断开当前连接
6.客户端连接指定的服务端端口
7.客户端向服务发出普通消息
8.客户端向服务端发出断开连接消息
目前只能实现群聊功能,还无法实现私聊
比如目前有ABC三个用户连接到服务端S,客户端都给服务端发消息,服务端都把在收到的消息广播给其他客户端
客户端代码:
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.*;
public class ChatClient {
private static final int PORT = 8888;
private static ExecutorService exec = Executors.newCachedThreadPool();
private String userId; //用户ID:使用客户端的IP+端口
public static void main(String[] args) throws Exception {
new ChatClient();
}
public ChatClient() {
Socket socket = null;
String msg;
try {
socket = new Socket("localhost", PORT);
//客户端连接到服务端之后,启动一个线程用于接收命令行输入,并且发送到服务端
exec.execute(new Sender(socket));
userId = socket.getInetAddress() + ":"+socket.getLocalPort();
println("[" + userId + "] 您好,欢迎来到阿飞聊天室!");
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
while (null != (msg = br.readLine())){
println(msg);
}
} catch (Exception e) { }
}
/**
* 客户端线程获取控制台输入消息,并且向服务发送消息
*/
static class Sender implements Runnable {
private Socket socket;
public Sender(Socket socket) {
this.socket = socket;
}
public void run() {
try {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
String msg;
while (true) {
//如果用户在命令行中按回车或输入空信息,则不发送到服务端
msg = br.readLine();
if (msg.length()==0){
print(socket.getLocalPort()+":>");
}else{
pw.println(msg);
continue;
}
//客户端发bye退出
if (msg.trim().equals("bye")) {
pw.close();
br.close();
break;
}
//测试消息
if (msg.equals("broadcast")){
msg = "这是来自"+socket.getInetAddress() + ":"+socket.getLocalPort() + " 的测试消息";
pw.println(msg);
}
}
pw.close();
br.close();
socket.close();
exec.shutdownNow();
} catch (Exception e) {
e.printStackTrace();
}
}
}
public static void print(Object o){
System.out.print(o);
}
public static void println(Object o){
System.out.println(o);
}
}
服务端代码:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.Collections;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ChatServer {
// 端口号
private static final int PORT = 8888;
//创建一个线程安全的的Socket列表,保存Socket对象
private static List<Socket> socketList = Collections.synchronizedList(new ArrayList<Socket>());
//线程池服务对象
private ExecutorService exec;
private ServerSocket server;
public static void main(String[] args) {
new ChatServer();
}
public ChatServer() {
try {
server = new ServerSocket(PORT);
//启动一个线程池
exec = Executors.newCachedThreadPool();
println("阿飞聊天室服务器已启动,监听 "+server.getInetAddress()+":"+server.getLocalPort() +" 端口");
Socket client = null;
while (true) {
//接收客户连接,该套接字将被添加到Socket列表列表中,并且创建一个新的服务线程
client = server.accept();
socketList.add(client);
exec.execute(new ChatTask(client));
}
} catch (IOException e) {
e.printStackTrace();
}
}
//为客户端服务的线程类,负责收发该socket对象的输入和输出信息
class ChatTask implements Runnable {
private Socket socket;
private BufferedReader bufferReader;
private PrintWriter writer;
private String msg;
private int isClosed=0;
private String userId; //用户ID:使用客户端的IP+端口
public ChatTask(Socket socket) throws IOException {
this.socket = socket;
bufferReader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
userId = this.socket.getInetAddress() +":"+this.socket.getPort();
msg = "[" + userId + "]进入聊天室!当前聊天室有"
+ socketList.size() + "人";
sendMessage(socket.getPort());//给所有人发消息
}
public void run() {
try {
while ( null != (msg = bufferReader.readLine())){
//服务端收到bye,关闭与该用户的连接
if (msg.trim().equals("bye")) {
socketList.remove(socket);
msg = "[" + userId + "]离开聊天室!当前聊天室有" + socketList.size() + "人";
sendMessage(socket.getPort()); //给别人发
break;
} else {
msg = "[" + userId+ "]说: " + msg;
sendMessage(socket.getPort()); //给别人发
}
try{
Thread.sleep(10);
}catch(Exception e){
e.printStackTrace();
}
}
//关闭服务,关闭的同时也就关闭了InputStream和outputStream,因此不必在上面关闭pw 和 br
socket.close();
bufferReader=null;
writer=null;
} catch (IOException e) {
//e.printStackTrace();
}
}
/**
* 群发消息给聊天室的其他人
*/
private void sendMessage(int selfPort) throws IOException { //Socket selfSocket,boolean toSelf
println(msg);
for (Socket client : socketList) {
if (client.getPort() != selfPort){
writer = new PrintWriter(client.getOutputStream(), true);
writer.println(msg);
}
}
}
}
public static void println(Object o){
System.out.println(o);
}
}
启动了服务端之后,然后再启动两个或多个客户端,在每个客户端窗口里直接输入要发送的消息按回车,该信息即可被广播到其他的客户端窗口
服务端图片:
客户端图片:
- 大小: 45.6 KB
- 大小: 35 KB
- 大小: 33.7 KB
分享到:
相关推荐
在这个“Socket实现简单聊天室”的项目中,我们可以通过Socket来构建一个基础的在线聊天系统。以下将详细阐述Socket编程的基本概念,以及如何利用它来创建聊天室。 首先,Socket是基于TCP/IP协议族的一种通信接口,...
总结起来,"用swing和socket实现的聊天室"项目涵盖了Java GUI编程、网络编程以及数据库操作等多个核心概念。通过这个项目,开发者可以锻炼到客户端-服务器架构的实现,理解Socket通信的原理,以及如何利用数据库存储...
在这个"Socket实现简单聊天室功能"的例子中,我们将会深入理解如何利用Socket来创建一个基本的聊天应用,使两台或多台电脑能够进行实时交互。 首先,我们需要了解Socket的基本概念。Socket可以被看作是网络上的端点...
在这个"Socket实现简易聊天室源码"中,我们可以深入理解Socket如何在客户端和服务器之间建立连接,进行数据传输,从而构建一个简单的聊天室系统。 首先,我们来看一下Socket的基本概念。Socket,也被称为套接字,是...
总的来说,实现“socket多人聊天”涉及到的知识点包括TCP/IP协议基础、Socket编程、线程处理、数据传输以及错误处理等。通过理解和掌握这些技术,我们可以构建出一个高效、可靠的多人聊天系统。在提供的压缩包文件中...
在这个“基于socket.io聊天室功能”的项目中,我们将探讨如何使用 Socket.IO 构建一个简单的聊天室应用。 1. **Socket.IO 的基本概念** - **事件驱动**:Socket.IO 的通信基于事件模型,客户端和服务器通过发送和...
当我们谈论“Linux下的Shell socket实现聊天室”时,我们实际上是在讨论如何利用Shell脚本结合socket编程来创建一个基本的网络通信环境,使得多用户可以通过网络进行实时的文本交流。这个聊天室应用通常包括两个主要...
本程序用winsocket 实现了一个基于c/s 架构的简单的聊天室程序。 采用面向连结的socket api, 信息发送、接收为阻塞同步方式。为实现多用户聊天,采用了服务器端分发线程处理,主线程阻塞接受客户端socket, 每接收...
本篇将深入探讨如何使用Socket实现一个简单的聊天室功能,包括服务端和客户端的代码实现。 一、Socket基础 Socket是网络通信的基本单元,它提供了进程间通信(IPC)的能力,尤其是跨越网络的进程间通信。在TCP/IP...
在本文中,我们将深入探讨如何使用C# WinForm和Socket通信技术来搭建一个简单的聊天室。Socket编程是网络通信的基础,而C# WinForm则提供了一个用户友好的图形界面,两者结合可以创建出功能丰富的交互式应用。 首先...
【C++聊天室Socket】是基于C++编程语言实现的网络通信系统,主要利用了Socket接口来构建一个简单的在线聊天平台。在计算机网络中,Socket是应用层与传输层之间的一个编程接口,允许应用程序通过它来进行网络通信。...
Socket实现的聊天室是一种基于网络通信的多用户交互平台,主要利用了Socket编程技术来构建。Socket在计算机网络中扮演着客户端与服务器间通信的重要角色,它为应用程序提供了低级别的、面向连接的、可靠的字节流网络...
在C#编程环境中,Socket和多线程技术的结合被广泛应用于网络通信,尤其是在构建聊天室这类实时交互的应用中。本项目"**C#Socket 多线程聊天室A**"是一个很好的学习资源,它展示了如何利用C#的Socket类进行网络通信...
Java的Socket实现的多人聊天程序是一个基于网络通信的项目,主要利用了Java的Socket类来构建客户端和服务端的通信桥梁。Socket是TCP/IP协议的一部分,它提供了两台计算机之间进行数据传输的基础。在这个项目中,...
本文将深入探讨如何使用C#语言实现一个基于TCP/IP协议的多线程Socket聊天室。这个聊天室功能允许局域网内的多台计算机进行实时信息交互,虽然没有在广域网环境下测试,但在局域网内能有效工作。 首先,我们要理解...
Socket编程是网络通信的核心技术,尤其在开发多人在线聊天室这样的应用中,它的重要性不言而喻。Socket,又称套接字,是操作系统提供的一种进程间通信机制,它允许两个或多个应用程序通过网络进行数据交换。在这个...
本文将深入探讨如何使用Socket来构建一个简单的聊天室程序。首先,我们理解Socket的概念:它是一种在网络之间建立连接并进行数据交换的机制,是应用层与传输层之间的接口。 在我们的示例中,"Client"和"Server"是两...
在本项目中,我们探讨的是一个使用Python编程语言实现的多人聊天室,它基于socket TCP通信协议,并且利用Tkinter库构建了用户友好的客户端界面。这个聊天室系统允许多个用户同时在线交流,增强了实时互动性。以下是...
【Socket + WinForm聊天室(经典)】 在IT领域,Socket编程是网络通信的基础,而WinForm则是.NET Framework中用于创建桌面应用的框架。本文将深入探讨如何利用Socket技术和WinForm构建一个经典的聊天室应用程序。 ...
### 用Java Socket 实现网络聊天室设计完美参考资料 #### 一、Socket简介及Java Socket支持 **Socket** 是一种用于网络通信编程的基础组件,它允许不同计算机之间通过TCP/IP协议进行数据交换。在计算机科学中,...