Hi guys,
I'm taking a Networking & Internet Systems module... have little experience working with java and am trying to work through an assignment... hopefully you can help!
The task is to implement a basic UDP chat system.
Create a simple chat system which uses the network (at least locally) to connect chat clients to a central chat server, which allows each client to communicate with each other via the server. The server receives messages from any client, and passes that message onto all other connected clients in a robust way.
–Server is started
–Client A sends a message
–Server sends message to all clients
–Client B sends a message
–Server sends message to all clients
–Etc etc etc
–Close Server
I can work through the basics of sending a message from the client to the server and getting a reply back... but i'm a bit stumped when there are multiple clients involved.
On the server side, i've tried to save all the client port numbers (who have sent a message to the server) into a HashSet and send out a reply to all clinets saved in the set... so i think this part is ok.
However, I thnk the client needs to be threaded also in order for this setup to work... but i'm a bit lost here... can anyone point me in the right direction...
Client & Server code below
Thanks
Client:
import java.io.*; // Imported because we need the InputStream and OuputStream classes
import java.net.*; // Imported because the Socket class is needed
public class Client {
public static void main(String args[]) throws Exception {
// The default port
int clientport = 7777;
String host = "localhost";
if (args.length < 1) {
System.out.println("Usage: UDPClient " + "Now using host = " + host + ", Port# = " + clientport);
}
// Get the port number to use from the command line
else {
//host = args[0];
clientport = Integer.valueOf(args[0]).intValue();
System.out.println("Usage: UDPClient " + "Now using host = " + host + ", Port# = " + clientport);
}
// Get the IP address of the local machine - we will use this as the address to send the data to
InetAddress ia = InetAddress.getByName(host);
SenderThread sender = new SenderThread(ia, clientport);
sender.start();
ReceiverThread receiver = new ReceiverThread(sender.getSocket());
receiver.start();
}
}
class SenderThread extends Thread {
private InetAddress serverIPAddress;
private DatagramSocket udpClientSocket;
private boolean stopped = false;
private int serverport;
public SenderThread(InetAddress address, int serverport) throws SocketException {
this.serverIPAddress = address;
this.serverport = serverport;
// Create client DatagramSocket
this.udpClientSocket = new DatagramSocket();
this.udpClientSocket.connect(serverIPAddress, serverport);
}
public void halt() {
this.stopped = true;
}
public DatagramSocket getSocket() {
return this.udpClientSocket;
}
public void run() {
try {
// Create input stream
BufferedReader inFromUser = new BufferedReader(new InputStreamReader(System.in));
while (true)
{
if (stopped)
return;
// Message to send
String clientMessage = inFromUser.readLine();
if (clientMessage.equals("."))
break;
// Create byte buffer to hold the message to send
byte[] sendData = new byte[1024];
// Put this message into our empty buffer/array of bytes
sendData = clientMessage.getBytes();
// Create a DatagramPacket with the data, IP address and port number
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, serverIPAddress, serverport);
// Send the UDP packet to server
udpClientSocket.send(sendPacket);
Thread.yield();
}
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
class ReceiverThread extends Thread {
private DatagramSocket udpClientSocket;
private boolean stopped = false;
public ReceiverThread(DatagramSocket ds) throws SocketException {
this.udpClientSocket = ds;
}
public void halt() {
this.stopped = true;
}
public void run() {
// Create a byte buffer/array for the receive Datagram packet
byte[] receiveData = new byte[1024];
while (true) {
if (stopped)
return;
// Set up a DatagramPacket to receive the data into
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
try {
// Receive a packet from the server (blocks until the packets are received)
udpClientSocket.receive(receivePacket);
// Extract the reply from the DatagramPacket
String serverReply = new String(receivePacket.getData(), 0, receivePacket.getLength());
// print to the screen
System.out.println("UDPClient: Response from Server: \"" + serverReply + "\"\n");
Thread.yield();
}
catch (IOException ex) {
System.err.println(ex);
}
}
}
}
Server:
import java.net.*; // Imported because the Socket class is needed
import java.util.HashSet;
public class Server {
private static HashSet<Integer> portSet = new HashSet<Integer>();
public static void main(String args[]) throws Exception {
// The default port
int serverport = 7777;
if (args.length < 1) {
System.out.println("Usage: UDPServer " + "Now using Port# = " + serverport);
}
// Get the port number & host to use from the command line
else {
serverport = Integer.valueOf(args[0]).intValue();
System.out.println("Usage: UDPServer " + "Now using Port# = " + serverport);
}
// Open a new datagram socket on the specified port
DatagramSocket udpServerSocket = new DatagramSocket(serverport);
System.out.println("Server started...\n");
while(true)
{
// Create byte buffers to hold the messages to send and receive
byte[] receiveData = new byte[1024];
// Create an empty DatagramPacket packet
DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
// Block until there is a packet to receive, then receive it (into our empty packet)
udpServerSocket.receive(receivePacket);
// Extract the message from the packet and make it into a string, then trim off any end characters
String clientMessage = (new String(receivePacket.getData())).trim();
// Print some status messages
System.out.println("Client Connected - Socket Address: " + receivePacket.getSocketAddress());
System.out.println("Client message: \"" + clientMessage + "\"");
// Get the IP address and the the port number which the received connection came from
InetAddress clientIP = receivePacket.getAddress();
// Print out status message
System.out.println("Client IP Address & Hostname: " + clientIP + ", " + clientIP.getHostName() + "\n");
// Get the port number which the recieved connection came from
int clientport = receivePacket.getPort();
//portSet.add(clientport);
// Response message
String returnMessage = clientMessage.toUpperCase();
// Create an empty buffer/array of bytes to send back
byte[] sendData = new byte[1024];
// Assign the message to the send buffer
sendData = returnMessage.getBytes();
for(Integer port : portSet)
{
if(port != clientport)
{
// Create a DatagramPacket to send, using the buffer, the clients IP address, and the clients port
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, clientIP, clientport);
// Send the echoed message
udpServerSocket.send(sendPacket);
}
}
}
}
}