public void run() { while(true) { //这里该线程就可以接受客户端的信息 try { ObjectInputStream ois=new ObjectInputStream(s.getInputStream()); Message m=(Message)ois.readObject(); System.out.println(m.getSender()+"给 "+m.getGetter()+"发送: "+m.getCon());//判断接受到客户端的信息 //拿到发送者与服务器的socket,此时就需要hashmap; SerConClientThread sc=ManageClientThread.getClientThread(m.getGetter()); ObjectOutputStream oos=new ObjectOutputStream(sc.s.getOutputStream()); //接受人的通信线程; oos.writeObject(m); } catch(Exception e) { e.printStackTrace(); } } }
时间: 2023-07-15 17:10:12 浏览: 90
这段代码是一个多线程的服务器端程序,用于接收客户端发送的消息,并将消息发送给指定的接收者。
程序的主要逻辑如下:
1. 服务器端通过 socket.accept() 方法监听客户端的连接请求,每当有新的客户端连接时,就会创建一个新的线程来处理该客户端的请求。
2. 在线程中,通过 ObjectInputStream 读取客户端发送的消息,并解析出消息的发送者、接收者以及消息内容。
3. 利用 ManageClientThread 类中维护的 HashMap,根据接收者的用户名获取对应的 SerConClientThread 对象,再通过其 socket 获取 ObjectOutputStream 对象,将消息发送给接收者。
4. 如果出现异常,则打印堆栈信息。
需要注意的是,这段代码还缺少了对客户端下线的处理。如果客户端下线,则需要将其对应的 SerConClientThread 对象从 HashMap 中删除。
相关问题
上述退出客户端和服务端的完整代码
以下是一个简单的客户端和服务端的实现,包含退出功能的代码示例:
客户端代码:
```java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.util.Objects;
import java.util.Scanner;
public class Client {
private static Socket socket;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
public static void main(String[] args) {
try {
// 连接服务端
socket = new Socket("localhost", 8888);
// 获取输出流和输入流
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// 启动读线程
new Thread(new ReadThread()).start();
// 向服务端发送消息
Scanner scanner = new Scanner(System.in);
while (true) {
String msg = scanner.nextLine();
oos.writeObject(msg);
oos.flush();
if("exit".equals(msg)) {
// 关闭网络连接和输入输出流
if(Objects.nonNull(socket)){
socket.close();
}
if(Objects.nonNull(oos)){
oos.close();
}
if(Objects.nonNull(ois)){
ois.close();
}
// 退出客户端
System.exit(0);
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static class ReadThread implements Runnable {
@Override
public void run() {
try {
while (true) {
String msg = (String) ois.readObject();
System.out.println("服务端说:" + msg);
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
```
服务端代码:
```java
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Objects;
public class Server {
private static ServerSocket serverSocket;
private static Socket socket;
private static ObjectOutputStream oos;
private static ObjectInputStream ois;
public static void main(String[] args) {
try {
// 创建ServerSocket并绑定端口
serverSocket = new ServerSocket(8888);
System.out.println("服务端已启动,等待客户端连接...");
// 等待客户端连接
socket = serverSocket.accept();
System.out.println("客户端已连接,地址:" + socket.getInetAddress());
// 获取输出流和输入流
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// 启动读线程
new Thread(new ReadThread()).start();
// 向客户端发送消息
while (true) {
String msg = "欢迎使用聊天室!";
oos.writeObject(msg);
oos.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private static class ReadThread implements Runnable {
@Override
public void run() {
try {
while (true) {
String msg = (String) ois.readObject();
System.out.println("客户端说:" + msg);
if("exit".equals(msg)) {
// 关闭网络连接和输入输出流
if(Objects.nonNull(socket)){
socket.close();
}
if(Objects.nonNull(oos)){
oos.close();
}
if(Objects.nonNull(ois)){
ois.close();
}
// 退出服务端
System.exit(0);
}
}
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
}
```
在上述代码中,客户端和服务端都可以通过发送exit消息来退出应用程序。当收到exit消息时,程序会关闭网络连接和输入输出流,并退出应用程序。
用Java代码多线程,集合,网络通信,GUI,IO,写一个租车App
好的,我可以帮你提供一个简单的租车App的Java代码示例,包括多线程、集合、网络通信、GUI、IO等方面。
首先,我们需要定义一个车辆类Car,包含车辆的基本信息:
```java
public class Car {
private String brand; // 品牌
private String model; // 型号
private double price; // 租金
private boolean isRented; // 是否已被租走
public Car(String brand, String model, double price) {
this.brand = brand;
this.model = model;
this.price = price;
this.isRented = false;
}
// getter和setter方法省略
}
```
接下来,我们定义一个租车公司类CarRentalCompany,用来管理车辆的租赁:
```java
import java.util.ArrayList;
import java.util.List;
public class CarRentalCompany {
private List<Car> cars; // 所有车辆列表
public CarRentalCompany() {
// 初始化车辆列表
cars = new ArrayList<>();
cars.add(new Car("Toyota", "Camry", 300));
cars.add(new Car("Honda", "Accord", 350));
cars.add(new Car("Nissan", "Altima", 320));
}
// 获取所有未被租走的车辆
public List<Car> getAvailableCars() {
List<Car> availableCars = new ArrayList<>();
for (Car car : cars) {
if (!car.isRented()) {
availableCars.add(car);
}
}
return availableCars;
}
// 租车
public void rentCar(Car car) {
car.setRented(true);
}
// 还车
public void returnCar(Car car) {
car.setRented(false);
}
}
```
我们还需要一个客户类Customer,用来租车和还车:
```java
public class Customer {
private String name; // 姓名
private CarRentalCompany company; // 所属租车公司
public Customer(String name, CarRentalCompany company) {
this.name = name;
this.company = company;
}
// 租车
public void rentCar(Car car) {
company.rentCar(car);
System.out.println(name + "租了一辆" + car.getBrand() + " " + car.getModel() + ",租金为" + car.getPrice() + "元/天。");
}
// 还车
public void returnCar(Car car) {
company.returnCar(car);
System.out.println(name + "还了一辆" + car.getBrand() + " " + car.getModel() + "。");
}
}
```
接下来,我们可以编写GUI界面,展示所有可租赁的车辆和已租赁的车辆,并提供租车和还车按钮。这里使用Swing库来实现GUI界面:
```java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
public class CarRentalApp extends JFrame implements ActionListener {
private CarRentalCompany company; // 租车公司
private List<Car> availableCars; // 所有未被租走的车辆
private List<Car> rentedCars; // 所有已被租走的车辆
private JList<Car> availableCarList; // 可租赁车辆列表
private JList<Car> rentedCarList; // 已租赁车辆列表
private JButton rentButton; // 租车按钮
private JButton returnButton; // 还车按钮
public CarRentalApp() {
company = new CarRentalCompany();
// 初始化GUI界面
setTitle("租车App");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(600, 400));
setLayout(new BorderLayout());
// 获取所有未被租走的车辆
availableCars = company.getAvailableCars();
// 获取所有已被租走的车辆
rentedCars = new ArrayList<>();
for (Car car : company.getCars()) {
if (car.isRented()) {
rentedCars.add(car);
}
}
// 可租赁车辆列表
availableCarList = new JList<>(availableCars.toArray(new Car[0]));
availableCarList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane availableScrollPane = new JScrollPane(availableCarList);
availableScrollPane.setPreferredSize(new Dimension(250, 300));
add(availableScrollPane, BorderLayout.WEST);
// 已租赁车辆列表
rentedCarList = new JList<>(rentedCars.toArray(new Car[0]));
rentedCarList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane rentedScrollPane = new JScrollPane(rentedCarList);
rentedScrollPane.setPreferredSize(new Dimension(250, 300));
add(rentedScrollPane, BorderLayout.EAST);
// 租车按钮
rentButton = new JButton("租车");
rentButton.addActionListener(this);
add(rentButton, BorderLayout.NORTH);
// 还车按钮
returnButton = new JButton("还车");
returnButton.addActionListener(this);
add(returnButton, BorderLayout.SOUTH);
pack();
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == rentButton) {
// 租车
Car selectedCar = availableCarList.getSelectedValue();
if (selectedCar != null) {
Customer customer = new Customer("张三", company);
customer.rentCar(selectedCar);
availableCars.remove(selectedCar);
rentedCars.add(selectedCar);
availableCarList.setListData(availableCars.toArray(new Car[0]));
rentedCarList.setListData(rentedCars.toArray(new Car[0]));
}
} else if (e.getSource() == returnButton) {
// 还车
Car selectedCar = rentedCarList.getSelectedValue();
if (selectedCar != null) {
Customer customer = new Customer("张三", company);
customer.returnCar(selectedCar);
rentedCars.remove(selectedCar);
availableCars.add(selectedCar);
availableCarList.setListData(availableCars.toArray(new Car[0]));
rentedCarList.setListData(rentedCars.toArray(new Car[0]));
}
}
}
public static void main(String[] args) {
new CarRentalApp();
}
}
```
最后,我们需要实现网络通信和IO操作,将租车信息写入文件和从文件中读取租车记录。这里我们采用Socket和ObjectOutputStream/ObjectInputStream来实现网络通信和对象的序列化:
```java
import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class CarRentalServer {
private List<Car> cars; // 所有车辆列表
private List<RentalRecord> rentalRecords; // 租车记录列表
public CarRentalServer() {
// 初始化车辆列表
cars = new ArrayList<>();
cars.add(new Car("Toyota", "Camry", 300));
cars.add(new Car("Honda", "Accord", 350));
cars.add(new Car("Nissan", "Altima", 320));
// 初始化租车记录列表
rentalRecords = new ArrayList<>();
// 启动服务器
try {
ServerSocket serverSocket = new ServerSocket(8888);
while (true) {
Socket socket = serverSocket.accept();
new ClientHandler(socket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
private synchronized void rentCar(String customerName, Car car) {
car.setRented(true);
rentalRecords.add(new RentalRecord(customerName, car, true));
}
private synchronized void returnCar(String customerName, Car car) {
car.setRented(false);
rentalRecords.add(new RentalRecord(customerName, car, false));
}
private void saveRentalRecords() {
try {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("rental_records.dat"));
oos.writeObject(rentalRecords);
oos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void loadRentalRecords() {
try {
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("rental_records.dat"));
rentalRecords = (List<RentalRecord>) ois.readObject();
ois.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
private class ClientHandler extends Thread {
private Socket socket;
public ClientHandler(Socket socket) {
this.socket = socket;
}
@Override
public void run() {
try {
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String command = (String) ois.readObject();
if (command.equals("rent")) {
String customerName = (String) ois.readObject();
Car car = (Car) ois.readObject();
rentCar(customerName, car);
} else if (command.equals("return")) {
String customerName = (String) ois.readObject();
Car car = (Car) ois.readObject();
returnCar(customerName, car);
} else if (command.equals("load")) {
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(cars);
oos.writeObject(rentalRecords);
oos.close();
} else if (command.equals("save")) {
saveRentalRecords();
}
ois.close();
socket.close();
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
new CarRentalServer();
}
}
```
客户端代码如下:
```java
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.net.Socket;
import java.util.List;
public class CarRentalClient extends JFrame implements ActionListener {
private List<Car> cars; // 所有车辆列表
private List<RentalRecord> rentalRecords; // 租车记录列表
private JList<Car> availableCarList; // 可租赁车辆列表
private JList<RentalRecord> rentalRecordList; // 租车记录列表
private JButton rentButton; // 租车按钮
private JButton returnButton; // 还车按钮
private JButton saveButton; // 保存按钮
public CarRentalClient() {
// 初始化GUI界面
setTitle("租车App");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(800, 400));
setLayout(new BorderLayout());
// 可租赁车辆列表
availableCarList = new JList<>();
availableCarList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane availableScrollPane = new JScrollPane(availableCarList);
availableScrollPane.setPreferredSize(new Dimension(250, 300));
add(availableScrollPane, BorderLayout.WEST);
// 租车记录列表
rentalRecordList = new JList<>();
rentalRecordList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
JScrollPane rentalScrollPane = new JScrollPane(rentalRecordList);
rentalScrollPane.setPreferredSize(new Dimension(500, 300));
add(rentalScrollPane, BorderLayout.EAST);
// 租车按钮
rentButton = new JButton("租车");
rentButton.addActionListener(this);
add(rentButton, BorderLayout.NORTH);
// 还车按钮
returnButton = new JButton("还车");
returnButton.addActionListener(this);
add(returnButton, BorderLayout.CENTER);
// 保存按钮
saveButton = new JButton("保存");
saveButton.addActionListener(this);
add(saveButton, BorderLayout.SOUTH);
pack();
setVisible(true);
// 从服务器加载数据
loadDataFromServer();
}
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == rentButton) {
// 租车
Car selectedCar = availableCarList.getSelectedValue();
if (selectedCar != null) {
try {
Socket socket = new Socket("localhost", 8888);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("rent");
oos.writeObject("张三");
oos.writeObject(selectedCar);
oos.close();
socket.close();
loadDataFromServer();
} catch (IOException ex) {
ex.printStackTrace();
}
}
} else if (e.getSource() == returnButton) {
// 还车
RentalRecord selectedRecord = rentalRecordList.getSelectedValue();
if (selectedRecord != null && selectedRecord.isRent()) {
try {
Socket socket = new Socket("localhost", 8888);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("return");
oos.writeObject("张三");
oos.writeObject(selectedRecord.getCar());
oos.close();
socket.close();
loadDataFromServer();
} catch (IOException ex) {
ex.printStackTrace();
}
}
} else if (e.getSource() == saveButton) {
// 保存租车记录
try {
Socket socket = new Socket("localhost", 8888);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("save");
oos.close();
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
private void loadDataFromServer() {
try {
Socket socket = new Socket("localhost", 8888);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("load");
oos.close();
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
cars = (List<Car>) ois.readObject();
rentalRecords = (List<RentalRecord>) ois.readObject();
ois.close();
socket.close();
// 更新GUI界面
availableCarList.setListData(cars.toArray(new Car[0]));
rentalRecordList.setListData(rentalRecords.toArray(new RentalRecord[0]));
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
new CarRentalClient();
}
}
```
这样,我们就完成了一个简单的租车App,并实现了多线程、集合、网络通信、GUI、IO等方面的应用。
阅读全文