Connection Refused - Java Client/Server - java

I'm trying to create a java push server model for testing on my own machine, this won't be used to connect external clients as the server and client will be on the same machine. After the client connects on the port specified by he/she, they should send a message of their choice that will be sent back to them, and any other clients connected to the same port.
The problem I'm having is i receive a java.net.ConnectException: Connection refused: connect when this is attempted. Below is the client and the server.
Edit: I've taken the time to ensure that the necessary ports are open too, and even disabled my firewall, but to no avail.
Server:
class MainServer {
// port that oir server is going to operate on
final static int port = 1234;
public static void main(String[] args) {
// this is going to model the server for the moment
System.out.println("Server has been started...");
Buffer<Messages> store = new Buffer<Messages>(10);
new Writer(store).start();
try {
ServerSocket serve = new ServerSocket(port);
while(true) {
// wait for server request
Socket socket = serve.accept();
// start thread to service request
new ServerThread(socket,store).start();
}
} catch(IOException e) {e.printStackTrace();}
}
}
class ServerThread extends Thread {
Socket socket;
Buffer<Messages> buffer;
public ServerThread(Socket s, Buffer<Messages> b) {
socket = s;buffer = b;
}
public void run() {
try {
DataInputStream in = new DataInputStream(socket.getInputStream());
int port = in.readInt();
System.out.println("Port: "+port);
Messages ms = new Messages(port);
// Read message as string from user
String message = in.readUTF();
int k = in.readInt();
while(k != -1) {
// Add message to array
// read next message
ms.add(message);
message = in.readUTF();
}
// close connection
socket.close();
// add message to buffer
buffer.put(ms);
} catch(IOException e) {e.printStackTrace();}
}
}
class Writer extends Thread {
Buffer<Messages> buffer;
public Writer(Buffer<Messages> m) {buffer = m;}
public void run() {
while(true) {
Messages dp = buffer.get();
dp.write();
}
}
}
class Buffer <E> {
/**
* Producer & Consumer Buffer
*/
private int max;
private int size = 0;
private ArrayList<E> buffer;
private Semaphore empty; //control consumer
private Semaphore full; // control producer
private Lock lock = new ReentrantLock();
public Buffer(int s) {
buffer = new ArrayList<E>();
max = s;
empty = new Semaphore(0);
full = new Semaphore(max);
}
// add data to our array
public void put(E x) {
try {
full.acquire();
} catch(InterruptedException e) {}
// sync update to buffer
lock.lock();
try {
buffer.add(x);
size++;
empty.release();
} finally {lock.unlock();}
}
public E get() {
try {
empty.acquire();
} catch(InterruptedException e) {}
// sync uodate on buffer
lock.lock();
try {
E temp = buffer.get(0);
buffer.remove(0);
size--;
full.release();
return temp;
} finally {lock.unlock();}
}
}
final class Messages {
private final int port;
private final ArrayList<String> data = new ArrayList<String>();
public Messages(int p) {port = p;}
void add(String message) {
data.add(message);
}
void write() {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// write message
out.write(data.size());
for(String k : data) {out.writeUTF(k);}
out.flush();
socket.close();
} catch(IOException e) {e.printStackTrace();}
}
}
Client:
class Client {
final static int nPort = 1234;
static int serverPort;
public static void main(String[] args) {
// this class and those present in it
// will model the client for assignment 8
Scanner in = new Scanner(System.in);
System.out.println("Please enter the messageboard number: ");
serverPort = in.nextInt();
System.out.println("Please type your message: ");
String msg = in.next();
Listener lis = new Listener(serverPort);
lis.start();
boolean go = true;
while(go) {
try {
Thread.sleep(2000);
} catch(InterruptedException e) {}
write(serverPort, msg);
System.out.println("Continue: 0/1");
int x = in.nextInt();
if(x == 0)go = false;
}
System.exit(0);
}
static void write(int port, String msg) {
try {
Socket socket;
socket = new Socket(InetAddress.getLocalHost(),port);
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
// send message to port
out.writeInt(port);
out.writeUTF(msg);
// write sentinal after message has been written and close socket
out.writeInt(-1);
out.flush();
socket.close();
} catch(IOException e) {System.out.println(e);}
}
}
class Listener extends Thread {
private int port;
volatile boolean go;
public Listener(int p) {p = port;}
public void run() {
try {
ServerSocket serversock = new ServerSocket(port);
while(go) {
Socket socket = serversock.accept();
DataInputStream in = new DataInputStream(socket.getInputStream());
// Read the message
while(in.available() > 0) {
String k = in.readUTF();
System.out.print(k+" ");
}
System.out.println();
socket.close();
}
} catch(IOException e) {go = false;}
}
}

Turns out i had a wrong assignment in my Listener class. I had p = port instead of port = p.
Solved. Through my own stupidity.

The hostname you are connecting to is localhost so you are assuming the server is on the same machine. If you need to connect to a different machine, you need to specify the host you want it to connect to.

Try changing socket = new Socket(InetAddress.getLocalHost(),port);
to
socket = new Socket(*IP OF SERVER (127.0.0.1 if same machine)*, port);

Related

Send to a server using a specific active thread

I have this class where i try to create a number of threads and then i need to send a message to the server over all the threads or using a specific thread. I can't seem to find a way to do that in this way I can only send using the last thread that was created.
Here is the class:
public class test{
public test(){
}
public static void main(String[] args){
MultiThreadChatClient mc = new MultiThreadChatClient();
test st = new test();
for(int i =0; i<=4; i++){
mc.createThreads();
}
while (true) {
System.out.print("type your message: ");
Scanner s = new Scanner(System.in);
String ss = s.nextLine();
ss = ss.trim().replaceAll(" +", " ");
mc.sendMessage(ss);
try
{
Thread.sleep(400);
}
catch(InterruptedException e)
{
// this part is executed when an exception (in this example InterruptedException) occurs
System.out.println("Exeption: " + e);
}
}
}
}
Here's the Client thread class:
public class MultiThreadChatClient implements Runnable {
// The client socket
private static Socket clientSocket = null;
// The output stream
private static PrintStream os = null;
// The input stream
private static BufferedReader br;
private static BufferedReader inputLine = null;
private static boolean closed = false;
public static void main(String[] args) {
// The default port.
int portNumber = 2222;
// The default host.
String host = "localhost";
if (args.length < 2) {
System.out.println("Usage: java MultiThreadChatClient <host> <portNumber>\n"
+ "Now using host=" + host + ", portNumber=" + portNumber);
} else {
host = args[0];
portNumber = Integer.valueOf(args[1]).intValue();
}
}
/*
* Open a socket on a given host and port. Open input and output streams.
*/
public void createThreads(){
try {
clientSocket = new Socket("localhost", 2222);
inputLine = new BufferedReader(new InputStreamReader(System.in));
os = new PrintStream(clientSocket.getOutputStream());
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
} catch (UnknownHostException e) {
System.err.println("Don't know about host " + 2222);
} catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to the host " + 2222);
}
//}
/*
* If everything has been initialized then we want to write some data to the
* socket we have opened a connection to on the port portNumber.
*/
if (clientSocket != null && os != null && br != null) {
new Thread(new MultiThreadChatClient()).start();
}
}
public void sendMessage(String mes){
os.println(mes);
}
/*
* Create a thread to read from the server. (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
String responseLine;
try {
while ((responseLine = br.readLine()) != null){
System.out.println(responseLine);
if (responseLine.indexOf("*** Bye") != -1)
break;
}
closed = true;
} catch (IOException e) {
System.err.println("IOException1234: " + e);
}
}
}
Here's the server code:
public class MultiThreadChatServerSync {
// The server socket.
private static ServerSocket serverSocket = null;
// The client socket.
private static Socket clientSocket = null;
// This chat server can accept up to maxClientsCount clients' connections.
private static final int maxClientsCount = 50;
private static final clientThread[] threads = new clientThread[maxClientsCount];
public static void main(String args[]) {
// The default port number.
int portNumber = 2222;
if (args.length < 1) {
System.out.println("Usage: java MultiThreadChatServerSync <portNumber>\n"
+ "Now using port number=" + portNumber);
} else {
portNumber = Integer.valueOf(args[0]).intValue();
}
/*
* Open a server socket on the portNumber (default 2222). Note that we can
* not choose a port less than 1023 if we are not privileged users (root).
*/
try {
serverSocket = new ServerSocket(portNumber);
//System.out.println(serverSocket.getPort());
} catch (IOException e) {
System.out.println(e);
}
/*
* Create a client socket for each connection and pass it to a new client
* thread.
*/
while (true) {
try {
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++) {
if (threads[i] == null) {
(threads[i] = new clientThread(clientSocket, threads)).start();
//System.out.println("A new client is created");
break;
}
}
if (i == maxClientsCount) {
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
}
class clientThread extends Thread {
MultiThreadChatServerSync ms = new MultiThreadChatServerSync();
private String clientName = null;
//private DataInputStream is = null;
private BufferedReader br = null;
private PrintStream os = null;
private Socket clientSocket = null;
private final clientThread[] threads;
private int maxClientsCount;
public clientThread(Socket clientSocket, clientThread[] threads) {
this.clientSocket = clientSocket;
this.threads = threads;
maxClientsCount = threads.length;
//System.out.println("Inside the Client thread");
}
public void run() {
MultiThreadChatServerSync mss = new MultiThreadChatServerSync();
int maxClientsCount = this.maxClientsCount;
clientThread[] threads = this.threads;
//System.out.println("Inside the run");
try {
/*
* Create input and output streams for this client.
*/
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
while (true) {
String line = br.readLine();
System.out.println("message received via Client port: " + clientSocket.getPort());
System.out.println("Received: " + line);
}
} catch (IOException e) {
}
}
}
So, is there a way to create 5 threads and then send the message over all of them or choose one specific thread out of them?
To be able to have a client which starts several sessions, and to be able to send data to one or several of them, the client must change in a few ways.
The static references in the client must be removed.
The Socket instances must be created and stored in the main thread (the writers will be used to send messages on behalf of one or more client sessions)
Each client session is now only responsible for reading (the reader is passed via the constructor).
The code is based on your original code, and meant to be a template for further enhancements: It will manage 5 client sessions, and be able to write to 1 or many.
The new main Thread (As an example, the Scanner will first ask the message for client #1, then 2, 3, 4 and next will broadcast to all, in a loop):
public class MultiThreadChatClientRunner {
final int NO_CLIENTS = 5;
//final String HOST_IP = "192.168.2.7";
final String HOST_IP = "localhost";
public static void main(String[] args) {
new MultiThreadChatClientRunner().start();
}
private void start() {
Socket[] sockets = new Socket[NO_CLIENTS];
PrintStream[] writers = new PrintStream[NO_CLIENTS];
BufferedReader[] readers = new BufferedReader[NO_CLIENTS];
for (int i = 0; i < NO_CLIENTS; i++) {
System.out.println("Creating client number "+i);
Socket clientSocket;
try {
clientSocket = new Socket(HOST_IP, 2222);
writers[i] = new PrintStream(clientSocket.getOutputStream());
readers[i] = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
new Thread(new MultiThreadChatClient(i, readers[i])).start();
} catch (IOException e) {
e.printStackTrace();
}
}
int clientId = 0;
Scanner s = new Scanner(System.in);
while (true) {
System.out.print("type your message for client #"+clientId);
String ss = s.nextLine();
ss = ss.trim().replaceAll(" +", " ");
writers[clientId].println(ss);
clientId = (clientId+1)%NO_CLIENTS;
// Test to broadcast to all clients
if (clientId == 4) {
for (int i = 0; i<NO_CLIENTS; i++)
writers[i].println("Broadcast message: "+ss);
}
try {
Thread.sleep(400);
} catch (InterruptedException e) {
System.out.println("Thread was interrupted");
break;
}
}
s.close();
}
}
The new client, which is much simpler than before:
public class MultiThreadChatClient implements Runnable {
// The client socket
private Socket clientSocket = null;
// The output stream
private PrintStream os = null;
// The input stream
private final BufferedReader br;
private final int clientId;
public MultiThreadChatClient(int clientId, BufferedReader br) {
super();
this.clientId = clientId;
this.br = br;
}
/*
* Create a thread to read from the server. (non-Javadoc)
*
* #see java.lang.Runnable#run()
*/
public void run() {
/*
* Keep on reading from the socket till we receive "Bye" from the
* server. Once we received that then we want to break.
*/
String responseLine;
try {
while ((responseLine = br.readLine()) != null) {
System.out.printf("Client #%d received message=%s\n", clientId, responseLine);
if (responseLine.indexOf("*** Bye") != -1)
break;
}
} catch (IOException e) {
System.err.println("IOException1234: " + e);
}
}
}
And the server, which is nearly identical, but manages closes better, and has some more logging to show which client is communicating.
public class MultiThreadChatServerSync {
// The server socket.
private static ServerSocket serverSocket = null;
// The client socket.
private static Socket clientSocket = null;
// This chat server can accept up to maxClientsCount clients' connections.
private static final int maxClientsCount = 50;
private static final ClientThread[] threads = new ClientThread[maxClientsCount];
public static void main(String args[]) {
// The default port number.
int portNumber = 2222;
if (args.length < 1) {
System.out.println(
"Usage: java MultiThreadChatServerSync <portNumber>\n" + "Now using port number=" + portNumber);
} else {
portNumber = Integer.valueOf(args[0]).intValue();
}
/*
* Open a server socket on the portNumber (default 2222). Note that we
* can not choose a port less than 1023 if we are not privileged users
* (root).
*/
try {
serverSocket = new ServerSocket(portNumber);
// System.out.println(serverSocket.getPort());
} catch (IOException e) {
System.out.println(e);
}
/*
* Create a client socket for each connection and pass it to a new
* client thread.
*/
while (true) {
try {
System.out.println("Awaiting a new connection on "+serverSocket.getLocalPort());
clientSocket = serverSocket.accept();
int i = 0;
for (i = 0; i < maxClientsCount; i++) {
if (threads[i] == null) {
(threads[i] = new ClientThread(i, clientSocket)).start();
// System.out.println("A new client is created");
break;
}
}
if (i == maxClientsCount) {
PrintStream os = new PrintStream(clientSocket.getOutputStream());
os.println("Server too busy. Try later.");
os.close();
clientSocket.close();
}
} catch (IOException e) {
System.out.println(e);
}
}
}
}
class ClientThread extends Thread {
private BufferedReader br = null;
private PrintStream os = null;
private final Socket clientSocket;
private final int clientId;
public ClientThread(int clientId, Socket clientSocket) {
this.clientSocket = clientSocket;
this.clientId = clientId;
}
public void run() {
try {
/*
* Create input and output streams for this client.
*/
br = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
os = new PrintStream(clientSocket.getOutputStream());
String line = "";
while ((line = br.readLine()) != null) {
System.out.printf("Client <%d> received message=<%s> via Client port: <%d>\n", clientId, line, clientSocket.getPort());
// Echo it back (as a test)
os.println(line);
}
br.close();
os.close();
clientSocket.close();
} catch (IOException e) {
}
System.out.println("Client has closed the session");
}
}
Let me know if you have any further questions at this time.

Why is DatagramPacket object get stuck when using one of it's methods? [duplicate]

This question already has an answer here:
Can not access object's properties(methods) from within the run method! Java Multithreading
(1 answer)
Closed 5 years ago.
I am using a server and a client to share information via UDP packets.
The client assembles a packet and sends it to the server.
The server receives the packet , and issues a thread to handle it.
In the threads code I try to use the packet but I get stuck for every method I use: getAddress() , getData() , etc.
When I try to use the packet's methods in the Server's code - it doesn't get stuck. Only in the Threads'.
I don't understand why I get stuck when using the packet in the thread's code
Here is the code and it compiles:
The Client
public class ExchangeClientProgram
{
public final double ERROR = 0;
private DatagramPacket packet;
private DatagramSocket socket;
private InetAddress hostAddress;
private int port;
private byte [] buf;
public ExchangeClientProgram(String hostIp , int port) throws SocketException, UnknownHostException
{
this.port = port;
socket = new DatagramSocket();
hostAddress = InetAddress.getByName(hostIp);
}
public boolean sendRequestPacket(ExchangeRequest exchangeRequest)
{
try
{
buf = ExchangeServerProgram.convertObjectToByteArr(exchangeRequest);
if(null != buf)
{
packet = new DatagramPacket(buf, buf.length, hostAddress , port);
socket.send(packet);
return true;
}
else
JOptionPane.showMessageDialog(null, "Sorry, this exchange cannot be trasnmitted to server");
} catch (IOException e){e.printStackTrace();}
return false;
}
}
The Server
public class ExchangeServerProgram extends Thread
{
public static final int DEFAULT_SERVER_PORT = 4444;
public static final int DEFAULT_BUFFER_SIZE = 1024;
private DatagramSocket socket;
private DatagramPacket packet;
private boolean listening = false;// default initial value
private byte[] buffer = new byte[DEFAULT_BUFFER_SIZE];
public ExchangeServerProgram() throws SocketException
{
socket = new DatagramSocket(DEFAULT_SERVER_PORT);
packet = new DatagramPacket(buffer , buffer.length);
}
public void run()
{
listening = true;
while(listening)
{
try
{
socket.receive(packet);
packet.getAddress(); // this line BEFORE the thread starts works fine.
new ExchangeClientRequestHandlerThread(packet ).start(); // inside this thread the trouble starts
// when using the SAME line from above
} catch (IOException e){e.printStackTrace();}
}
}
public static byte [] convertObjectToByteArr(Object obj)
{
ByteArrayOutputStream bos = new ByteArrayOutputStream();
byte [] buffer = null;
ObjectOutput out = null;
try {
out = new ObjectOutputStream(bos);
out.writeObject(obj);
out.flush();
buffer = bos.toByteArray();
}
catch (IOException e){e.printStackTrace(); }
finally {
try
{
bos.close();
} catch (IOException e){e.printStackTrace(); }
}
return buffer;
}
}
The Thread Handling The Packet, here is where I get stuck
public class ExchangeClientRequestHandlerThread extends Thread
{
private DatagramPacket packet;
public ExchangeClientRequestHandlerThread(DatagramPacket packet)
{
this.packet = packet;
}
public void run()
{
if(null == packet)
return;
packet.getAddress(); //... get stuck here
System.out.println("doesn't get to this code line");
}
}
ExchangeRequest
public class ExchangeRequest implements Serializable
{
private static final long serialVersionUID = -1355753051547829379L;
private String coinFrom;
private String coinTo;
private double amount;
private int requestId;
public ExchangeRequest(String coinFrom, String coinTo, double amount , int requestId)
{
this.coinFrom = coinFrom;
this.coinTo = coinTo;
this.amount = amount;
this.requestId = requestId;
}
//getters & setters
}
Main
public class Main
{
public static void main(String [] args)
{
try
{
ExchangeServerProgram server = new ExchangeServerProgram();
server.start(); // starts the server
String inputIpAddress = "localhost";
ExchangeClientProgram clientProgram = new ExchangeClientProgram(inputIpAddress, ExchangeServerProgram.DEFAULT_SERVER_PORT);
ExchangeRequest request = new ExchangeRequest("usd", "euro", 4, 1111); // 1111 is just an ID number for the message
clientProgram.sendRequestPacket(request);
while(true)
{
// this while loop is just for the example
// here I am waiting for received packet
// via "socket.receive();"
}
} catch (SocketException | UnknownHostException e)
{
e.printStackTrace();
}
}
}
Threading is your problem. You have one thread calling receive(packet), and when you receive it you pass it to another thread for processing, making the first thread call receive(packet) again.
The problem is that receive synchronizes on packet and methods in DatagramPacket are synchronized, so while the first thread is blocked on receive(packet) you can't call any of the DatagramPacket methods without it blocking the thread.
Possible solutions include processing the packet in the original thread or creating a new DatagramPacket for each receive().

Multi-Threaded Server Chat Java - Connecting but no messages

Trying to build a simple multi-threaded chat server that runs via command prompt. The clients do connect to the server and the server will hold multiple clients, however when trying to send messages from one client to the other, or even notifying a client of another user logging in, nothing comes up on the client command prompt.
public class Server {
private static ServerSocket servSock;
private static Socket clientSock;
private static ArrayList<ClientThread> clientList;
private static int IDcount = 0;
public static void main(String args[]){
// Get command line arguments.
if (args.length != 3) {
System.out.println("Required arguments: server port, block duration, timeout");
return;
}
int port = Integer.parseInt(args[0]);
int blockDur = Integer.parseInt(args[1]);
int timeout = Integer.parseInt(args[2]);
try{
servSock = new ServerSocket(port);
clientList = new ArrayList<ClientThread>();
}
catch(IOException ex){
System.err.println(ex);
}
while (true) {
try {
clientSock = servSock.accept();
ClientThread thread = new ClientThread(clientSock);
clientList.add(thread);
thread.start();
} catch (IOException e) {
System.out.println(e);
}
}
}
private synchronized static void broadcast(String msg){
System.out.print(msg);
for(int i = 0; i < clientList.size(); i++){
ClientThread client = clientList.get(i);
client.send(msg);
}
}
synchronized static void unlist(int id){
for(int i = 0; i < clientList.size(); i++){
ClientThread thread = clientList.get(i);
if(thread.id == id){
clientList.remove(i);
return;
}
}
}
static class ClientThread extends Thread {
Socket sock;
BufferedReader tIn;
PrintWriter tOut;
int id;
String username;
String msg;
ClientThread(Socket sock){
id = IDcount++;
this.sock = sock;
try{
tIn = new BufferedReader(new InputStreamReader(sock.getInputStream()));
tOut = new PrintWriter(sock.getOutputStream());
username = tIn.readLine();
broadcast(username + " logged in");
}
catch(IOException ex){
System.err.println(ex);
}
}
public void run(){
boolean loggedIn = true;
while(loggedIn){
try{
msg = tIn.readLine();
}
catch (IOException ex){
System.err.println(ex);
}
String[] parts = msg.split("\\s",2);
String type = parts[0];
Client code is similar
public class Client{
private static Socket clientSock;
private static BufferedReader in;
private static PrintWriter out;
private static Scanner scan;
public static void main(String[] args) throws IOException {
if (args.length != 2) {
System.out.println("Required arguments: server IP, server port");
return;
}
String host = args[0];
int port = Integer.parseInt(args[1]);
clientSock = new Socket(host, port);
in = new BufferedReader(new InputStreamReader(clientSock.getInputStream()));
out = new PrintWriter(clientSock.getOutputStream());
scan = new Scanner(System.in);
new ListenFromServer().start();
boolean online = true;
System.out.println("Enter your username:");
String username = scan.nextLine();
out.println(username);
while(online){
System.out.println("> ");
String msg = scan.nextLine();
String[] parts = msg.split("\\s");
String type = parts[0];
send(msg);
if(type.equalsIgnoreCase("logout")){
online = false;
}
}
logoff();
}
static void send(String msg) throws IOException{
out.println(msg);
}
private static void logoff() throws IOException{
in.close();
out.close();
scan.close();
clientSock.close();
}
static class ListenFromServer extends Thread{
public void run(){
while(true){
try{
String msg = in.readLine();
System.out.println(msg);
}
catch(IOException ex){
System.err.println(ex);
}
}
}
}
}
When you send data with PrintWriter.println(), data write to buffer. You must call PrintWriter.flush() after println to send data to or from the server immediately.
And when you call username = tIn.readLine(); in ClientThread constructor, you block main-thread, because constructor calls in main-thread. So, while connected user won't send username, other clients can't connect.

Chat Program: Client to Client Chat

Currently I'm working on this mini chat program in Java where multiple users should be able to log into the chat program and chat. Right now what my program does is log in users (Clients) to the Server, and what ever they say gets echoed back by the Server. What I want to do is be able to send a request to chat with another client directly.
My idea was to create a Hash map that holds the username of the client and its socket. When a client requests to chat with another client it looks for that user's username in the HashMap and if the other client agrees to chat then it connects the sockets.
I'm not sure how to implement this and also my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why. I've been trying to get this working for a while now, starting to give me headaches.
Here's the code:
Client Class:
package source;
import java.io.*;
import java.util.*;
import java.net.*;
public class Client implements Runnable {
private Socket socket;
private DataOutputStream dout;
private DataInputStream din;
// Constructor
public Client() {
// Code
}
public Client(String host, int port) {
try {
socket = new Socket(host, port);
System.out.println("connected to " + socket);
din = new DataInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
new Thread(this).start();
} catch (IOException ie) {
System.out.println(ie);
}
}
private void processMessage(String message) {
try {
dout.writeUTF(message);
} catch (IOException ie) {
System.out.println(ie);
}
}
public void run() {
try {
while (true) {
String message = din.readUTF();
System.out.println(message);
}
} catch (IOException ie) {
System.out.println(ie);
}
}
public static void main(String[] args) throws IOException {
while (true) {
String prompt;
Scanner clientPrompt = new Scanner(System.in);
System.out.println("client> ");
prompt = clientPrompt.next();
if (prompt.equals("Emmanuel"))
System.out.println("God With Us");
else if (prompt.equals("goOnline")) {
// Enter a host name
// Enter a portNumber
// Enter a userName
String h, p, u;
System.out.println("Enter hostname: ");
h = clientPrompt.next();
System.out.println("Enter portNumber: ");
p = clientPrompt.next();
System.out.println("Enter userName: ");
u = clientPrompt.next();
goOnline(h, p, u);
} else if (prompt.equals("Exit")) {
clientPrompt.close();
System.exit(1);
} else {
System.out.println("Invalid Input, Try Again");
}
}
}
public static void goOnline(String host, String port, String userName) {
int portNumber = Integer.parseInt(port);
Client c = new Client(host, portNumber);
c.processMessage("Username: " + userName);
String prompt;
Scanner clientPrompt = new Scanner(System.in);
while (true) {
prompt = clientPrompt.next();
c.processMessage(prompt);
c.run();
if (prompt.equals("Exit")) {
System.out.println("Bye Bye");
clientPrompt.close();
}
}
}
}
Server Class:
package source;
import java.io.*;
import java.net.*;
import java.util.*;
public class Server { // The ServerSocket we'll use for accepting new
// connections
private ServerSocket ss;
private HashMap<String, Socket> userInfo = new HashMap<String, Socket>();
// A mapping from sockets to DataOutputStreams.
private Hashtable<Socket, DataOutputStream> outputStreams = new Hashtable<Socket, DataOutputStream>();
// Constructor and while-accept loop all in one.
public Server(int port) throws IOException {
// All we have to do is listen
listen(port);
}
private void listen(int port) throws IOException {
// ServerSocket
ss = new ServerSocket(port);
System.out.println("Listening on " + ss);
while (true) {
Socket s = ss.accept();
System.out.println("Connection from " + s);
DataOutputStream dout = new DataOutputStream(s.getOutputStream());
DataOutputStream userInfo = new DataOutputStream(s.getOutputStream());
outputStreams.put(s, dout);
outputStreams.put(s, userInfo);
new ServerThread(this, s);
}
}
Enumeration<DataOutputStream> getOutputStreams() {
return outputStreams.elements();
}
void sendToAll(String message) {
for (Enumeration<DataOutputStream> e = getOutputStreams(); e.hasMoreElements();) {
// Output Stream
DataOutputStream dout = (DataOutputStream) e.nextElement();
// Send Message
try {
dout.writeUTF(message);
} catch (IOException ie) {
System.out.println(ie);
}
}
}
// Remove socket,
void removeConnection(Socket s) {
// Synchronize
synchronized (outputStreams) {
// Tell the world
System.out.println("Removing connection to " + s);
// Remove it from hashtable
outputStreams.remove(s);
try {
s.close();
} catch (IOException ie) {
System.out.println("Error closing " + s);
ie.printStackTrace();
}
}
}
void addInfo(String user, Socket s) {
userInfo.put(user, s);
}
// Main
static public void main(String args[]) throws Exception {
// Get port
int port = Integer.parseInt(args[0]);
// Create Server object
new Server(port);
}
}
ServerThread:
package source;
import java.io.*;
import java.util.*;
import java.net.*;
public class ServerThread extends Thread { // The Server that spawned us
private Server server;
private Socket socket;
public ServerThread(Server server, Socket socket) {
this.server = server;
this.socket = socket;
start();
}
public void run() {
try {
DataInputStream din = new DataInputStream(socket.getInputStream());
while (true) {
String message = din.readUTF();
StringTokenizer stt = new StringTokenizer(message, " ");
while (stt.hasMoreTokens()) {
String token = stt.nextToken();
if (token.equals("Username:")) {
String username = stt.nextToken();
server.addInfo(username, socket);
}
}
System.out.println("Sending " + message);
server.sendToAll(message);
if (message.equals("Exit")) {
System.out.println("Bye Bye");
server.removeConnection(socket);
System.exit(1);
}
}
} catch (EOFException ie) {
} catch (IOException ie) {
ie.printStackTrace();
} finally {
server.removeConnection(socket);
}
}
}
my program only takes one input from the user and returns it from the Server and after that it stops I have no idea why?
Just do one change as mentioned below at client side to resolve above issue.
public void run() {
try {
// while (true) { // remove an infinite loop that will block
// the client thread to accept next message
String message = din.readUTF();
System.out.println(message);
// }
} catch (IOException ie) {
System.out.println(ie);
}
}
Doubt: (client side)
You have started a thread then why are you calling run() method directly.

Server Send Out message from one client to all Clients conneted. JAVA

I am writing a Server/Client chat where basically Multiple Clients connected to One Server. One client send a message to server Then all other Clients will get the same message. For example: Client A, B, C Connected to A same Server. Client A send Message To Server, Server then will send the same message to client B and C but exclude Client A.
I'm stuck at part where Server send out the message to all other clients.
Below is the code, I'm just a Java beginner so any help with the code will be much appreciate.
ServerSide
public class ServerP2P extends Thread{
private ServerSocket server = null;
private Socket clientSocket = null;
private ArrayList<ServerThread> clientThreadList = new ArrayList<>();
private int maxClient = 4;
private int port = 9990;
boolean listening = true;
public ServerP2P(){
try{
server = new ServerSocket(port);
}catch(IOException e){
e.printStackTrace();
return;
}
System.out.println("Server with Port "+port+" is Up and Running");
}
public void run(){
System.out.println("Room Chat Is Up");
while(listening){
for(int i = 0;i<clientThreadList.size();i++){
if(!clientThreadList.get(i).getConneection()){
System.out.println(clientThreadList.get(i)+" is removing from server because there is no conntection");
clientThreadList.remove(i);
}
}
try{
clientSocket = server.accept();
}catch(Exception e){
e.printStackTrace();
}
System.out.println("User with IP "+clientSocket.getInetAddress()+" Has Connected to Server");
clientThreadList.add(new ServerThread(clientSocket));
try{
Thread.sleep(200);
}catch(Exception e){
e.printStackTrace();
}
}
}
public ArrayList<ServerThread> listOFClient(){
return clientThreadList;
}
public static void main(String[] args){
ServerP2P server = new ServerP2P();
server.start();
}
}
ServerThread
public class ServerThread{
private Socket clientSocket;
private boolean connected;
private Incomming incommingData;
String msg = null;
private class Incomming extends Thread{
private DataInputStream input;
public void run(){
try{
input = new DataInputStream(clientSocket.getInputStream());
}catch(IOException e){
e.printStackTrace();
return;
}
System.out.println("User with IP "+clientSocket.getInetAddress()+" has connected");
while(true){
try{
Thread.sleep(200);
int msgSize = input.readInt();
byte[] msgByte = new byte[msgSize];
for(int i = 0; i < msgSize ; i++){
msgByte[i] = input.readByte();
}
msg = new String(msgByte);
System.out.println(msg);
}catch(Exception e){
e.printStackTrace();
}
}
}
}
public ServerThread(Socket newClientSocket){
this.clientSocket = newClientSocket;
connected = true;
incommingData = new Incomming();
incommingData.start();
}
public boolean getConneection(){
return connected;
}
public void closeConnection(){
try{
connected = false;
clientSocket.close();
}catch(Exception e){
e.printStackTrace();
}
}
}
ClientSide
public class ClientP2P{
private Socket serverSocket = null;;
private DataOutputStream output = null;
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
public static void main(String[] args) {
ClientP2P client = new ClientP2P();
client.startConnect();;
}
public void startConnect(){
int port = 9990;
try {
serverSocket = new Socket("localhost", port);
System.out.println(serverSocket.isBound());
output = new DataOutputStream(serverSocket.getOutputStream());
System.out.println("Please Enter Your name: ");
String nameClient = reader.readLine();
output.writeInt(nameClient.length());
output.writeBytes(nameClient);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("You Are Connected");
System.out.println("Chat Can Start");
sendText();
}
public void sendText(){
try {
while (true) {
System.out.println("Type Message: ");
String msg = reader.readLine();
output.writeInt(msg.length());
output.writeBytes(msg);
System.out.println("Message sent");
recivedText();
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void recivedText(){
try{
DataInputStream input = new DataInputStream(serverSocket.getInputStream());
int textSize = 0;
while(input.available() != 0){
byte[] byteString = new byte[textSize];
for(int i = 0; i < textSize;i++){
byteString[i] = input.readByte();
}
String txtServer = new String(byteString);
System.out.println(txtServer);
textSize = 0;
}
sendText();
}catch(Exception e){
e.printStackTrace();
}
}
}
Thanks For Your Time Guys.
Your ServerThread receives the messages and you want to send them to all other clients. One way you could achieve is to have the clients register themselves with the Server (this would help in the server not knowing the clients when it starts, which ideally should be the case). In your ServerThread, get a list of available clients from the server and loop through them and send the message to each one of them.
Use ObserverDesign pattern to hold the list of all your buddy/user to whom you wish to send message. Use HashMap to maintain a list of all the observer and its socket. Once the message is received, you retrieve the sockets of each user and write the same message on each socket.

Categories

Resources