-
Notifications
You must be signed in to change notification settings - Fork 0
/
server.java
146 lines (121 loc) · 6.12 KB
/
server.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
package MyChat;
import java.io.*;
import java.net.*;
import java.util.*;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
class Server {
static ServerSocket serverSocket;
static List<PrintStream> connectedClients = new ArrayList<>();
public static void main(String[] args) throws Exception {
int defaultPort = 1025;
hostServer(defaultPort);
}
// Starts the server on the specified port number
private static void hostServer(int portNumber) throws Exception {
serverSocket = new ServerSocket(portNumber);
if (serverSocket != null) {
displayConnectionDetails();
handleClientConnection();
} else {
System.err.println("\n [Server Connection] Error Occurred \n");
}
}
// Displays the details of the server connection
private static void displayConnectionDetails() {
System.out.println("\n [ Local Server: Online (" + serverSocket.getLocalSocketAddress() + ") "
+ DateTimeFormatter.ofPattern("E, dd-MMM-yyyy/HH:mm:ss").format(LocalDateTime.now())
+ " (" + TimeZone.getDefault().getDisplayName() + ") ] ");
}
/**
* Accepts client connections in a loop. For each client connection, it creates a new thread to handle the client's requests
* Within the thread, it reads input from the client's input stream and sends output through the client's output stream
*/
private static void handleClientConnection() throws IOException {
while (true) {
Socket clientSocket = serverSocket.accept();
System.out.println("\n[*] Client Connected: " + clientSocket.hashCode());
Thread clientThread = new Thread(() -> {
try {
BufferedReader inputStream = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
PrintStream outputStream = new PrintStream(clientSocket.getOutputStream());
String clientName = getClientName(clientSocket, inputStream, outputStream);
processClientMessage(clientName, inputStream, outputStream);
} catch (IOException | InterruptedException exc) {
exc.printStackTrace();
}
});
clientThread.start();
}
}
/**
* Prompts the client to enter a name and performs validation
* If a valid name is entered, it prints the client's name, the host-port details and sends a welcome message
*/
private static String getClientName(Socket clientSocket, BufferedReader inputStream, PrintStream outputStream) throws IOException, InterruptedException {
String clientName = null;
while (true) {
outputStream.print("Name: ");
clientName = inputStream.readLine().trim();
if (!clientName.isEmpty()) {
System.out.println("User: " + clientName);
System.out.println("Host-Port: " + clientSocket.getRemoteSocketAddress() + "\n");
outputStream.println("\n +--------------------------------------------+\n"
+ " | Welcome To MyChat (v1.0) [UID: " + clientSocket.hashCode() + "] |\n"
+ " +--------------------------------------------+\n");
Thread.sleep(2000);
break;
} else {
outputStream.println("\n [Server] Invalid Name \n");
}
}
return clientName;
}
/**
* If the client sends the message "Logout", it disconnects the client and notifies other clients
* Otherwise, it broadcasts the message to all connected clients and indicates whether the message was delivered successfully
*/
private static void processClientMessage(String clientName, BufferedReader inputStream, PrintStream outputStream) throws IOException, InterruptedException {
synchronized (connectedClients) {
connectedClients.add(outputStream);
for (PrintStream clientOutput : connectedClients) {
if (clientOutput != outputStream) {
clientOutput.println("\n\n [Server] " + clientName + " is Online "
+ "(" + DateTimeFormatter.ofPattern("HH:mm").format(LocalDateTime.now()) + ")\n");
}
}
}
while (true) {
outputStream.print("[" + clientName + "] ");
String messageLine = inputStream.readLine();
if (messageLine.equalsIgnoreCase("Logout")) {
System.out.println("\n[*] Client Disconnected: " + clientName);
outputStream.println("\n [Server Disconnected] ");
outputStream.print("Session lasted for: ");
break;
} else {
synchronized (connectedClients) {
System.out.println(" [" + DateTimeFormatter.ofPattern("dd/MMM/yyyy HH:mm:ss").format(LocalDateTime.now()) + "] "
+ "[" + clientName + "] " + messageLine);
for (PrintStream clientOutput : connectedClients) {
if (clientOutput != outputStream) {
clientOutput.println("\n\n[" + clientName + "] " + messageLine);
clientOutput.println(" ".repeat(20) + "(Message Received)\n");
}
}
outputStream.println(" ".repeat(20) + "(Message Delivered)\n");
Thread.sleep(250);
}
}
}
synchronized (connectedClients) {
for (PrintStream clientOutput : connectedClients) {
if (clientOutput != outputStream) {
clientOutput.println("\n\n [Server] " + clientName + " is Offline "
+ "(" + DateTimeFormatter.ofPattern("HH:mm").format(LocalDateTime.now()) + ")\n");
}
}
connectedClients.remove(outputStream);
}
}
}