1 客户端向服务器注册自己的信息,包括IP地址、端口号、用户名等; 2.2 客户端启动后向服务器查询其它用户在线状态,包括用户名、IP地址、端口号等; 2.3 客户端之间建立直接连接,实现一对一的信息交换; 2.4 服务器端维护用户的状态信息,对用户查询做出响应
时间: 2024-04-15 17:27:47 浏览: 22
要实现客户端向服务器注册信息和查询其他用户在线状态,你可以对服务器端的代码进行修改。下面是修改后的示例代码:
1. 服务器端代码:
```java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class Server {
private static final int PORT = 8888;
private List<ClientHandler> clients = new ArrayList<>();
public void start() {
try {
ServerSocket serverSocket = new ServerSocket(PORT);
System.out.println("服务器已启动,监听端口:" + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("有新的客户端连接:" + clientSocket.getInetAddress().getHostAddress());
ClientHandler clientHandler = new ClientHandler(clientSocket);
clients.add(clientHandler);
new Thread(clientHandler).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
public void broadcastMessage(String message) {
for (ClientHandler client : clients) {
client.sendMessage(message);
}
}
public String getOnlineUsers() {
StringBuilder users = new StringBuilder("在线用户列表:\n");
for (ClientHandler client : clients) {
users.append(client.getUsername()).append(" - ")
.append(client.getClientSocket().getInetAddress().getHostAddress()).append(":")
.append(client.getClientSocket().getPort()).append("\n");
}
return users.toString();
}
private class ClientHandler implements Runnable {
private Socket clientSocket;
private InputStream inputStream;
private OutputStream outputStream;
private String username;
public ClientHandler(Socket clientSocket) {
this.clientSocket = clientSocket;
}
public Socket getClientSocket() {
return clientSocket;
}
public String getUsername() {
return username;
}
@Override
public void run() {
try {
inputStream = clientSocket.getInputStream();
outputStream = clientSocket.getOutputStream();
byte[] buffer = new byte[1024];
int len;
// 注册客户端信息
len = inputStream.read(buffer);
String registration = new String(buffer, 0, len);
username = registration.split(",")[0];
while ((len = inputStream.read(buffer)) > 0) {
String message = new String(buffer, 0, len);
System.out.println("收到客户端消息:" + message);
broadcastMessage(message); // 转发消息给其他客户端
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
clientSocket.close();
clients.remove(this);
System.out.println("有客户端断开连接:" + clientSocket.getInetAddress().getHostAddress());
System.out.println(getOnlineUsers());
} catch (IOException e) {
e.printStackTrace();
}
}
}
public void sendMessage(String message) {
try {
outputStream.write(message.getBytes());
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.start();
}
}
```
2. 客户端代码:
```java
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.Scanner;
public class Client {
private static final String SERVER_IP = "localhost";
private static final int SERVER_PORT = 8888;
private String username;
public void start() {
try {
Socket socket = new Socket(SERVER_IP, SERVER_PORT);
System.out.println("成功连接服务器");
InputStream inputStream = socket.getInputStream();
OutputStream outputStream = socket.getOutputStream();
// 注册客户端信息
System.out.print("请输入用户名:");
Scanner scanner = new Scanner(System.in);
username = scanner.nextLine();
String registration = username + "," + socket.getLocalAddress().getHostAddress() + "," + socket.getLocalPort();
outputStream.write(registration.getBytes());
outputStream.flush();
// 接收服务器发送的消息
new Thread(() -> {
try {
byte[] buffer = new byte[1024];
int len;
while ((len = inputStream.read(buffer)) > 0) {
String message = new String(buffer, 0, len);
System.out.println("收到服务器消息:" + message);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
// 发送消息给服务器或建立直接连接
new Thread(() -> {
try {
while (true) {
System.out.println("请选择操作:");
System.out.println("1. 发送消息给服务器");
System.out.println("2. 查询在线用户");
System.out.println("3. 建立直接连接");
System.out.print("请输入操作选项:");
int option = scanner.nextInt();
scanner.nextLine(); // 读取换行符
switch (option) {
case 1:
System.out.print("请输入消息:");
String message = scanner.nextLine();
outputStream.write(message.getBytes());
outputStream.flush();
break;
case 2:
outputStream.write("query_users".getBytes());
outputStream.flush();
break;
case 3:
System.out.print("请输入对方的IP地址:");
String ip = scanner.nextLine();
System.out.print("请输入对方的端口号:");
int port = scanner.nextInt();
scanner.nextLine(); // 读取换行符
Socket directSocket = new Socket(ip, port);
System.out.println("成功建立直接连接");
// 接收直接连接的消息
new Thread(() -> {
try {
InputStream directInputStream = directSocket.getInputStream();
byte[] directBuffer = new byte[1024];
int directLen;
while ((directLen = directInputStream.read(directBuffer)) > 0) {
String directMessage = new String(directBuffer, 0, directLen);
System.out.println("收到直接连接消息:" + directMessage);
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
// 发送消息给直接连接
new Thread(() -> {
try {
OutputStream directOutputStream = directSocket.getOutputStream();
while (true) {
System.out.print("请输入直接连接消息:");
String directMessage = scanner.nextLine();
directOutputStream.write(directMessage.getBytes());
directOutputStream.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
break;
default:
System.out.println("无效选项");
}
}
} catch (IOException e) {
e.printStackTrace();
}
}).start();
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
Client client = new Client();
client.start();
}
}
```
以上修改后的代码实现了客户端向服务器注册自己的信息,并且可以通过服务器查询其他用户的在线状态。客户端还可以选择建立直接连接与其他客户端进行一对一的信息交换。服务器端维护用户的状态信息,并对用户查询做出响应。