Files
2026-06-12 12:18:48 +03:30

135 lines
6.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Network File-Sharing chat System (Java)
### Overview
This project is a multi-client network chat system with file sharing, implemented using **Java sockets**, **MUltithreading** and **Object Serialization**.
Clients connect to a central server and can:
* send public chat message
* send private messages
* request the list of online users
* transfer files to other users
communication between client and server is implemented using Java Object Streams(`ObjectInputStream` / `ObjectOutputStream`) so that structured objects can be transferred directly over the network.
---
### Architecture
1. **ChatServer** opens a `ServerSocket` and waits for connections.
2. Each connecting client gets its own **ClientSession** thread.
3. A shared **UserManager** tracks who's online and routes messages.
4. Everything is exchanged as serialized objects (`ChatMessage` / `FileMessage`).
```
Client → Socket → Server → ClientSession (thread) → UserManager → Broadcast/Route → Clients
```
---
### Message Protocol
Two serializable classes carry everything over the wire:
* **ChatMessage** text-based: logins, public/private messages, user-list requests, server replies.
* **FileMessage** file transfers, carrying the file as a `byte[]`.
`MessageType` is an enum (`LOGIN`, `LOGIN_SUCCESS`, `LOGIN_FAILED`, `PUBLIC_MESSAGE`, `PRIVATE_MESSAGE`, `USER_LIST`, …) so both sides agree on what each message means.
---
### Package Structure
```
com.university.chat
├── common → shared message classes (ChatMessage, FileMessage, MessageType)
├── server → server-side logic
└── client → client application
```
#### `common`
Already complete — these define the protocol and don't need any changes.
#### `server`
* **ChatServer** entry point. Opens the server socket and creates a `ClientSession` per client.
* **ClientSession** one thread per client. Handles login, reads incoming messages, and dispatches them (broadcast, private message, user list, file transfer).
* **UserManager** thread-safe registry of online users (`ConcurrentHashMap<String, ClientSession>`). Already complete.
* **FileManager** manages per-user folders on disk (`server_data/<username>/sent` and `received`). Already complete.
#### `client`
* **chatClient** entry point. Connects to the server, logs in, starts a listener thread, and runs the input loop for user commands.
* **ServerListener** background thread that continuously reads and displays messages/files coming from the server.
* **TransferProgress** small helper that prints a progress bar during file uploads. Already complete.
---
### Client Commands
```
/msg <username> <message> → private message
/users → list online users
/sendfile <username> <filepath> → send a file
<anything else> → public message
```
---
### File Transfer Flow
1. Client reads the file and converts it to `byte[]`.
2. It's wrapped in a `FileMessage` and sent to the server.
3. The server saves a copy (in `sent/` for the sender, `received/` for the receiver) and forwards it to the recipient.
---
### Threading Model
* **Server**: one `ClientSession` thread per connected client.
* **Client**: main thread handles user input, a `ServerListener` thread handles incoming messages — so you can chat and receive **at the same time**.
---
## Your Task
Several core pieces are left as **TODOs** for you to implement. Follow the comments in each file alongside the structure mentioned above to complete them.
| File | What to implement |
|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `Server/ChatServer.java` | Pick a port, create a shared `UserManager`, open the server socket, accept clients in a loop, and create a `ClientSession` thread per client. |
| `Server/ClientSession.java` | Set up object streams in the constructor; handle login (success/failure); receive messages in a loop and dispatch `ChatMessage`/`FileMessage`; broadcast, private message, and user-list logic; remove user on disconnect; forward files. |
| `Client/chatClient.java` | Connect to the server, set up streams, log in, start `ServerListener`, and implement the command loop (`/msg`, `/users`, `/sendfile`, plain messages). |
| `Client/ServerListener.java` | Continuously read objects from the server and print chat messages / file-received notifications. |
**Tips:**
* Always create the `ObjectOutputStream` *before* the `ObjectInputStream` on both ends — this avoids a stream-handshake deadlock.
* Don't forget `out.flush()` after `writeObject(...)`.
* Test with two or more client instances to verify broadcasting, private messages, and file transfer all work correctly.
#### Running multiple clients in IntelliJ
1. Click the **⋮** icon next to the run button → **Edit Configurations**
2. Open **Modify options** (Alt+M)
3. Enable **Allow multiple instances** (Alt+U)
---
## Optional Bonus: JavaFX UI
If you want to go further replace the console client with a simple **JavaFX** GUI (chat window, online-user list, file-send button, etc.).
1. **Add the JavaFX dependencies** to your `pom.xml` — for Maven:
```xml
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-controls</artifactId>
<version>21</version>
</dependency>
<dependency>
<groupId>org.openjfx</groupId>
<artifactId>javafx-fxml</artifactId>
<version>21</version>
</dependency>
```
You'll also need the `javafx-maven-plugin` to run the app from Maven.
2. **Create a JavaFX entry point**, e.g. `Client/ChatClientApp.java`, extending `javafx.application.Application` and implementing `start(Stage stage)`. This becomes your new launch class instead of (or alongside) `chatClient`.
3. Reuse your existing socket/streams logic — just move the "send" actions to button handlers and update the UI from `ServerListener` using `Platform.runLater(...)` (**since UI updates must happen on the JavaFX Application Thread**).
This part is **completely optional** and won't affect your core grade — just a fun way to practice connecting a GUI to networking code and multithreading.