basic client/server structure
This commit is contained in:
@@ -1,5 +0,0 @@
|
||||
public class App {
|
||||
public static void main(String[] args) throws Exception {
|
||||
System.out.println("Hello, World!");
|
||||
}
|
||||
}
|
||||
15
ChatApp/src/ChatApp.java
Normal file
15
ChatApp/src/ChatApp.java
Normal file
@@ -0,0 +1,15 @@
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import client.Client;
|
||||
import server.Server;
|
||||
|
||||
public class ChatApp {
|
||||
public static void main(String[] args) throws Exception {
|
||||
Server server = new Server(6665);
|
||||
Client client = new Client(new InetSocketAddress("localhost", 6665));
|
||||
|
||||
while (true) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
35
ChatApp/src/client/Client.java
Normal file
35
ChatApp/src/client/Client.java
Normal file
@@ -0,0 +1,35 @@
|
||||
package client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
|
||||
import network.protocol.packets.LoginPacket;
|
||||
import network.protocol.packets.SendChatMessagePacket;
|
||||
|
||||
public class Client {
|
||||
|
||||
private final ClientConnexion connexion;
|
||||
|
||||
public Client(InetSocketAddress serverAddress) throws SocketException {
|
||||
this.connexion = new ClientConnexion(new DatagramSocket(), serverAddress);
|
||||
login("Moi");
|
||||
}
|
||||
|
||||
private void login(String pseudo) {
|
||||
try {
|
||||
this.connexion.sendPacket(new LoginPacket(pseudo));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void SendChatMessage(String message) {
|
||||
try {
|
||||
this.connexion.sendPacket(new SendChatMessagePacket(message));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
94
ChatApp/src/client/ClientConnexion.java
Normal file
94
ChatApp/src/client/ClientConnexion.java
Normal file
@@ -0,0 +1,94 @@
|
||||
package client;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import network.PacketHandler;
|
||||
import network.SocketReader;
|
||||
import network.SocketWriter;
|
||||
import network.protocol.Packet;
|
||||
import network.protocol.PacketVisitor;
|
||||
import network.protocol.packets.ChatMessagePacket;
|
||||
import network.protocol.packets.CreateRoomPacket;
|
||||
import network.protocol.packets.JoinRoomPacket;
|
||||
import network.protocol.packets.LeaveRoomPacket;
|
||||
import network.protocol.packets.LoginPacket;
|
||||
import network.protocol.packets.RequestRoomListPacket;
|
||||
import network.protocol.packets.RoomListPacket;
|
||||
import network.protocol.packets.SendChatMessagePacket;
|
||||
import network.protocol.packets.ServerResponsePacket;
|
||||
|
||||
public class ClientConnexion implements PacketVisitor, PacketHandler{
|
||||
|
||||
private final InetSocketAddress serverAddress;
|
||||
private final SocketWriter writer;
|
||||
private final SocketReader reader;
|
||||
|
||||
public ClientConnexion(DatagramSocket socket, InetSocketAddress serverAddress) {
|
||||
this.serverAddress = serverAddress;
|
||||
this.writer = new SocketWriter(socket);
|
||||
this.reader = new SocketReader(socket, this);
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.reader.stop();
|
||||
}
|
||||
|
||||
public void sendPacket(Packet packet) throws IOException {
|
||||
this.writer.sendPacket(packet, serverAddress);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket(Packet packet, InetSocketAddress address) {
|
||||
// we assume that the packet comes from the server
|
||||
visit(packet);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(ChatMessagePacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(CreateRoomPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(JoinRoomPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(LeaveRoomPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(LoginPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(RequestRoomListPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(RoomListPacket packet) {
|
||||
System.out.println("Handled room list !");
|
||||
// throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(SendChatMessagePacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(ServerResponsePacket packet) {
|
||||
System.out.println(packet.getResponse());
|
||||
}
|
||||
|
||||
}
|
||||
9
ChatApp/src/network/PacketHandler.java
Normal file
9
ChatApp/src/network/PacketHandler.java
Normal file
@@ -0,0 +1,9 @@
|
||||
package network;
|
||||
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import network.protocol.Packet;
|
||||
|
||||
public interface PacketHandler {
|
||||
void handlePacket(Packet packet, InetSocketAddress address);
|
||||
}
|
||||
48
ChatApp/src/network/SocketReader.java
Normal file
48
ChatApp/src/network/SocketReader.java
Normal file
@@ -0,0 +1,48 @@
|
||||
package network;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import network.protocol.Packet;
|
||||
|
||||
public class SocketReader {
|
||||
|
||||
private final DatagramSocket socket;
|
||||
private final Thread readThread;
|
||||
private final PacketHandler handler;
|
||||
|
||||
public SocketReader(DatagramSocket socket, PacketHandler handler) {
|
||||
this.socket = socket;
|
||||
this.handler = handler;
|
||||
this.readThread = new Thread(this::readLoop);
|
||||
this.readThread.start();
|
||||
}
|
||||
|
||||
public void stop() {
|
||||
this.readThread.interrupt();
|
||||
}
|
||||
|
||||
private void readLoop() {
|
||||
while (!Thread.interrupted()) {
|
||||
try {
|
||||
byte[] buffer = new byte[65535];
|
||||
DatagramPacket dataPacket = new DatagramPacket(buffer, buffer.length);
|
||||
socket.receive(dataPacket);
|
||||
|
||||
InetSocketAddress address = new InetSocketAddress(dataPacket.getAddress(), dataPacket.getPort());
|
||||
|
||||
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(dataPacket.getData()));
|
||||
Packet packet = (Packet) ois.readObject();
|
||||
|
||||
this.handler.handlePacket(packet, address);
|
||||
} catch (IOException | ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
30
ChatApp/src/network/SocketWriter.java
Normal file
30
ChatApp/src/network/SocketWriter.java
Normal file
@@ -0,0 +1,30 @@
|
||||
package network;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.DatagramPacket;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import network.protocol.Packet;
|
||||
|
||||
public class SocketWriter {
|
||||
|
||||
private final DatagramSocket socket;
|
||||
|
||||
public SocketWriter(DatagramSocket socket) {
|
||||
this.socket = socket;
|
||||
}
|
||||
|
||||
public void sendPacket(Packet packet, InetSocketAddress address) throws IOException {
|
||||
ByteArrayOutputStream stream = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(stream);
|
||||
oos.writeObject(packet);
|
||||
oos.flush();
|
||||
byte[] data = stream.toByteArray();
|
||||
DatagramPacket dataPacket = new DatagramPacket(data, data.length, address.getAddress(),
|
||||
address.getPort());
|
||||
this.socket.send(dataPacket);
|
||||
}
|
||||
}
|
||||
52
ChatApp/src/server/Server.java
Normal file
52
ChatApp/src/server/Server.java
Normal file
@@ -0,0 +1,52 @@
|
||||
package server;
|
||||
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import network.PacketHandler;
|
||||
import network.SocketReader;
|
||||
import network.protocol.Packet;
|
||||
|
||||
public class Server implements PacketHandler {
|
||||
|
||||
private final DatagramSocket serverSocket;
|
||||
private final Map<InetSocketAddress, ServerConnexion> connexions;
|
||||
private final SocketReader reader;
|
||||
private final ArrayList<String> roomNames;
|
||||
|
||||
public Server(int port) throws SocketException {
|
||||
this.serverSocket = new DatagramSocket(port);
|
||||
this.connexions = new HashMap<>();
|
||||
this.reader = new SocketReader(serverSocket, this);
|
||||
this.roomNames = new ArrayList<>();
|
||||
}
|
||||
|
||||
public ArrayList<String> getRoomNames() {
|
||||
return roomNames;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
this.reader.stop();
|
||||
}
|
||||
|
||||
public boolean hasChatterName(String pseudo) {
|
||||
for (var entry : this.connexions.entrySet()) {
|
||||
if (pseudo.equals(entry.getValue().getChatterName()))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePacket(Packet packet, InetSocketAddress address) {
|
||||
if (!connexions.containsKey(address)) {
|
||||
this.connexions.put(address, new ServerConnexion(this, serverSocket, address));
|
||||
}
|
||||
this.connexions.get(address).visit(packet);
|
||||
}
|
||||
|
||||
}
|
||||
98
ChatApp/src/server/ServerConnexion.java
Normal file
98
ChatApp/src/server/ServerConnexion.java
Normal file
@@ -0,0 +1,98 @@
|
||||
package server;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.DatagramSocket;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
import network.SocketWriter;
|
||||
import network.protocol.Packet;
|
||||
import network.protocol.PacketVisitor;
|
||||
import network.protocol.packets.ChatMessagePacket;
|
||||
import network.protocol.packets.CreateRoomPacket;
|
||||
import network.protocol.packets.JoinRoomPacket;
|
||||
import network.protocol.packets.LeaveRoomPacket;
|
||||
import network.protocol.packets.LoginPacket;
|
||||
import network.protocol.packets.RequestRoomListPacket;
|
||||
import network.protocol.packets.RoomListPacket;
|
||||
import network.protocol.packets.SendChatMessagePacket;
|
||||
import network.protocol.packets.ServerResponsePacket;
|
||||
import network.protocol.packets.ServerResponsePacket.Response;
|
||||
|
||||
public class ServerConnexion implements PacketVisitor {
|
||||
|
||||
private final Server server;
|
||||
private final InetSocketAddress clientAddress;
|
||||
private final SocketWriter writer;
|
||||
private String chatterName;
|
||||
|
||||
public ServerConnexion(Server server, DatagramSocket socket, InetSocketAddress clientAddress) {
|
||||
this.clientAddress = clientAddress;
|
||||
this.server = server;
|
||||
this.writer = new SocketWriter(socket);
|
||||
}
|
||||
|
||||
public String getChatterName() {
|
||||
return this.chatterName;
|
||||
}
|
||||
|
||||
public void sendPacket(Packet packet) {
|
||||
try {
|
||||
this.writer.sendPacket(packet, clientAddress);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(ChatMessagePacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(CreateRoomPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(JoinRoomPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(LeaveRoomPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(LoginPacket packet) {
|
||||
if (server.hasChatterName(packet.getPseudo())) {
|
||||
sendPacket(new ServerResponsePacket(Response.AuthError));
|
||||
return;
|
||||
}
|
||||
|
||||
this.chatterName = packet.getPseudo();
|
||||
sendPacket(new RoomListPacket(server.getRoomNames()));
|
||||
System.out.println("[Server] Chatter " + packet.getPseudo() + " connected !");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(RequestRoomListPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(RoomListPacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(SendChatMessagePacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPacket(ServerResponsePacket packet) {
|
||||
throw new UnsupportedOperationException("Unimplemented method 'visitPacket'");
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user