一、所需实现功能
一个群聊系统,多个用户之间可以相互通信
二、简单分析
多个客户端,连接到服务器端,服务器端从发出消息的客户端接受消息,
并将消息发送给其他客户端。
三、代码实现
- 一、使用PrintStream流,为读取时readLine();提供换行符
- 二、采用多线程避免线程阻塞,读取或传达数据不及时
- 三、ArrayList sockets;实现多用户
- 四、客户端和服务器端的ip和端口号必须一致
服务器Server端
Server类
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
/**
* @Description:服务器端
* @Author:Zc9741
* @QQ:516906531
*/
public class Server {
private int port;
private ServerSocket serverSocket;
//private Socket socket;
private ArrayList<Socket> sockets;
public Server(int port) {
this.port = port;
sockets=new ArrayList<>();
}
public void start(){
//创建ServerSocket对象
try {
serverSocket=new ServerSocket(port);
} catch (IOException e) {
e.printStackTrace();
}
//等待链接
while(true) {
try {
Socket socket = serverSocket.accept();
sockets.add(socket);
System.out.println("连接成功");
//创建一个线程用于发送数据
Thread send=new Thread(new Runnable() {
@Override
public void run() {
Scanner sc= null;
PrintStream ps=null;
try {
sc=new Scanner(System.in);
ps=new PrintStream(socket.getOutputStream());
while (sc.hasNext()){
ps.println(sc.nextLine());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
sc.close();
ps.close();
}
}
});
send.start();
//创建一个线程用于接受数据
Thread receive=new Thread(new Runnable() {
@Override
public void run() {
try {
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line=null;
while ((line=br.readLine())!=null){
for (Socket socket1 : sockets) {
//判断是否为当前客户端
if(socket!=socket1){
PrintStream ps = new PrintStream(socket1.getOutputStream());
ps.println(line);
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
receive.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
MyClass(主方法)
public class MyClass {
public static void main(String[] args) throws Exception {
Server server = new Server(8888);//端口号(1024,15555);
server.start();
}
}
客户Client端
Client类
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
/**
* @Description:客户端
* @Author:Zc9741
* @QQ:516906531
*/
public class Client {
private int port;//服务器端的端口号
private String ipAddr;//ip地址
private Socket socket;
public Client(int port, String ipAddr) {
this.port = port;
this.ipAddr = ipAddr;
}
public void start(){
//创建链接
try {
socket=new Socket(ipAddr,port);
System.out.println("官人,人家好了!");
} catch (IOException e) {
e.printStackTrace();
}
//创建一个线程用于发送数据
Thread send=new Thread(new Runnable() {
@Override
public void run() {
Scanner sc= null;
PrintStream ps=null;
try {
sc=new Scanner(System.in);
ps=new PrintStream(socket.getOutputStream());
while (sc.hasNext()){
ps.println(sc.nextLine());
}
} catch (IOException e) {
e.printStackTrace();
}finally {
sc.close();
ps.close();
}
}
});
send.start();
//创建一个线程用于接受数据
Thread receive=new Thread(new Runnable() {
@Override
public void run() {
try {
BufferedReader br=new BufferedReader(new InputStreamReader(socket.getInputStream()));
String line=null;
while ((line=br.readLine())!=null){
System.out.println(line);
}
} catch (IOException e) {
e.printStackTrace();
}
}
});
receive.start();
}
}
MyClass类
public class MyClass {
public static void main(String[] args) throws Exception {
Client client = new Client(8888, "127.0.0.1");
client.start();
}
}
四、测试
通过复制Client端代码实现多用户
依次开启服务器端和客户端(提示链接成功后开始交互,绿色字体为本机操作,白色字体为他机数据)