Socket communication in JavaFX - java

I'm trying to develop an email server which is able to manage three or more clients. Now I'm focusing only on the first client. The mechanism I'm using is this: The client sends its email address (a String) to the server, so he can get into the right directory and extracts the texts from the .txt (which are the emails). This is the structure of the Server directory:
$package
|
+------------+----------------------------+
| | |
Server.java ServerController.java email#email.com/
|
+
+--------|---------+
1.txt 2.txt 3.txt
This is the ServerController file, which is the one that executes the threads:
public class ServerController {
#FXML
private TextArea textarea;
public void initModel() {
try {
int i = 1;
ServerSocket s = new ServerSocket(5000);
while (true) {
Socket incoming = s.accept(); // si mette in attesa di richiesta di connessione e la apre
textarea.setText("Waiting for connections");
Runnable r = new ThreadedEchoHandler(incoming, i);
new Thread(r).start();
i++;
}
} catch (IOException e) {
e.printStackTrace();
}
}
class ThreadedEchoHandler implements Runnable {
private Socket incoming;
private int counter;
/**
* Constructs a handler.
*
* #param i the incoming socket
* #param c the counter for the handlers (used in prompts)
*/
public ThreadedEchoHandler(Socket in, int c) {
incoming = in;
counter = c;
}
public void run() {
String nomeAccount = "";
try {
//PHASE 1: The server receives the email
try {
InputStream inStream = incoming.getInputStream();
Scanner in = new Scanner(inStream);
nomeAccount = in.nextLine(); //ricevo il nome
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
incoming.close();
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
//PHASE 2: I'm getting all the emails from the files
File dir = new File(nomeAccount);
String[] tmp = new String[5];
ArrayList<Email> arr = new ArrayList<Email>();
DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
int i = 0;
for (File file : dir.listFiles()) {
if (file.isFile()) {
Scanner input = new Scanner(System.in);
input = new Scanner(file);
while (input.hasNextLine()) {
tmp[i++] = input.nextLine();
}
input.close();
}
Date data = df.parse(tmp[4]);
arr.add(new Email((Integer.parseInt(tmp[0])), tmp[1], nomeAccount, tmp[2], tmp[3], data));
i = 0;
}
//PHASE 3: The server sends the ArrayList to the client
try {
ObjectOutputStream objectOutput = new ObjectOutputStream(incoming.getOutputStream());
objectOutput.writeObject(arr);
} catch (IOException e) {
e.printStackTrace();
}
} catch (FileNotFoundException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} catch (ParseException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
} finally {
try {
incoming.close();
} catch (IOException ex) {
Logger.getLogger(ServerController.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
As you can see I divide it into phases to better understand the mechanism. In the client I've a DataModel which is the one who memorize the email list and that establish the connection with the socket. This is the code:
public void loadData() throws IOException {
Socket s = new Socket("127.0.0.1", 5000);
System.out.println("I've created the socket");
ArrayList<Email> email = new ArrayList<Email>();
//PHASE 1: The client sends a string to the server
try {
InputStream inStream = s.getInputStream();
OutputStream outStream = s.getOutputStream();
PrintWriter out = new PrintWriter(outStream, true /* autoFlush */);
out.print(account); //Sends account name
//PHASE 2: The client receives the ArrayList with the emails
ObjectInputStream objectInput = new ObjectInputStream(s.getInputStream()); //Error Line!
try {
Object object = objectInput.readObject();
email = (ArrayList<Email>) object;
System.out.println(email.get(1));
} catch (ClassNotFoundException e) {
System.out.println("The list list has not come from the server");
e.printStackTrace();
}
} finally {
s.close();
}
//Casting the arrayList
emailList = FXCollections.observableArrayList(email);
//Sorting the emails
Collections.sort(emailList, new Comparator<Email>() {
public int compare(Email o1, Email o2) {
if (o1.getData() == null || o2.getData() == null) {
return 0;
}
return o1.getData().compareTo(o2.getData());
}
});
}
The problem is that when I execute the server I don't get any error but the GUI doesn't load and on the prompt I cannot see any output. If I execute the Client (while the server is running) I only get the message System.out.println("I've created the socket"); but nothing happens after that. What should I modify to let the two sockets communicates?

Using Sockets is bad idea at all. You don't need direct connection.
It's better to use something like REST service with GET and POST.
so you can manage any clients count. Just send response to get and post.
Also you can use tokens.

Related

How can i measure my local server's response time?

I am using a server-client based architecture with sockets in java on my localhost and I need to know how much it takes my localhost to send a response, any ideas on how I can measure that?
(i am using 2 separate classes for listening to the keyboard and the server at the same time)
This is my Clients main function:
public static void main(String[] args) throws IOException {
Socket socket = new Socket(SERVER_IP,SERVER_PORT);
ServerConnection connection = new ServerConnection(socket);
BufferedReader keyboard = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(socket.getOutputStream(),true);
new Thread(connection).start();
while(true){
String command = keyboard.readLine();
if(command == "quit"){
break;
}
out.println(command);
}
socket.close();
System.exit(0);
}
This is my server connection class's run method where I listen to te server.
#Override
public void run() {
String res = null;
try {
while (true) {
res = in.readLine();
if (res==null) break;
System.out.println("Server>: " + res);
}
} catch (IOException e) {
e.printStackTrace();
}finally {
try {
in.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
so in other words I am sending the request from one class and receiving it in another class.

TCP client and server; cmd prompt using object streams issue [duplicate]

I have one client file clientRPC.java and server file serverRPC.java. Both communicate using TCP protocol and use objectinput and output stream to transfer data.
my client file:
public class clientRPC {
public static void main(String args[]) {
Socket s = null;
try {
int serverPort = 8888;
s = new Socket("localhost", serverPort);// server name is local host
//initializing input and output streams object and referencing them to get input and output
ObjectInputStream in = null;
ObjectOutputStream out = null;
out = new ObjectOutputStream(s.getOutputStream());
in = new ObjectInputStream(s.getInputStream());
MathsTutor mt = new MathsTutor();
out.writeObject(mt);
out.flush();
System.out.println("Welcome to Maths Tutor Service. The available maths exercises are:\n"
+ "Addition: Enter 'A' or 'a'\n"
+ "Subtraction: Enter 'S' or 's'\n"
+ "Multiplication: Enter 'M' or 'm'\n"
+ "Division: Enter 'D' or 'd'\n"
+ "Enter 'Q' or 'q' to quit");
//System.out.println();
MathsTutor mt1 = (MathsTutor) in.readObject();
String response = in.readUTF();
System.out.println(response);
} catch (UnknownHostException e) {
System.out.println("Socket:" + e.getMessage());
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
if (s != null) {
try {
s.close();
} catch (IOException e) {
System.out.println("close:" + e.getMessage());
}
}
}
}
}
and my server file :
public class serverRPC extends Thread {
String request;
String response;
public static void main(String args[]) {
try {
int serverPort = 8888;
ServerSocket listen_socket = new ServerSocket(serverPort);
while (true) {
Socket clientSocket = listen_socket.accept();
Connection c = new Connection(clientSocket);
}
} catch (IOException e) {
System.out.println("Listen socket:" + e.getMessage());
}
public serverRPC(String s) {
request = s;
}
}
class Connection extends Thread {
ObjectInputStream in;
ObjectOutputStream out;
Socket clientSocket;
public Connection(Socket aClientSocket) {
try {
clientSocket = aClientSocket;
in = new ObjectInputStream(clientSocket.getInputStream());
out = new ObjectOutputStream(clientSocket.getOutputStream());
this.start();
} catch (IOException e) {
System.out.println("Connection:" + e.getMessage());
}
}
public void run() {
try {
MathsTutor mt = (MathsTutor) in.readObject();
InetAddress ip = clientSocket.getInetAddress();
System.out.println("The Received Message from Client at address:/" + ip.getHostAddress());
System.out.println("====================================");
MathsTutor mt1 = new MathsTutor();
out.writeObject(mt1);
while(true) {
// Read from input
String command = in.readUTF();
System.out.println(command);
}
//System.out.println();
} catch (EOFException e) {
System.out.println("EOF:" + e.getMessage());
} catch (IOException e) {
System.out.println("readline:" + e.getMessage());
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} finally {
try {
clientSocket.close();
} catch (IOException e) {/*close failed*/
}
}
}
}
The problem is when I run server and then client on cmd, the client side displays the welcome msg and puts cursor on another line for user input but, I can't type anything, the cursor just blinks... I know this might be simple but it has taken already 3 hours for me and I'm stuck in the same thing.
The cursor marked with red keeps blinking but doesn't let me type anything.
You're writing an object with writeObject() and trying to read it with readUTF(). Illogical.
objects written with writeObject() must be read with readObject().
strings written with writeUTF() must be read with readUTF().
primitives written with writeXXX() must be read with readXXX(), for most values of X.

Tcp output/input doesnt work

I'm trying to change my game to use TCP, but I can't even get it to work.
The client connects successfully with the server, but for some reason I can't
receive messages from server nor receive messages from client. My guess is that I'm doing something wrong with the output/input?
Here is the server code:
public class Server implements Runnable {
Server() {
serverSocket = new ServerSocket(1919, 300);
}
run() {
while (true) {
String message = "blank";
try {
//w8ting for some connection
tcpSOCKET = tcpServer.accept(null);
//Connected to some1!
input = new BufferedReader(new InputStreamReader(
tcpSOCKET.getInputStream()));
output = new DataOutputStream(
tcpSOCKET.getOutputStream());
output.flush();
//TODO PROBLEM it stays here trying to read line but even if the client send a message it wont move on
message = input.readLine();
main.addLabel(Color.BLUE, message);
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
And this is the client:
public class Client implements Runnable {
Client() { }
run() {
String message = "";
try {
tcpSOCKET = new Socket(serverIp, serverTCPport);
input = new BufferedReader(new InputStreamReader(
tcpSOCKET.getInputStream()));
output = new DataOutputStream(tcpSOCKET.getOutputStream());
output.flush();
while (true) {
System.out.println("w8ting for message from server");
//TODO problem, it wont read anything even if the server send a message
message = input.readLine();
System.out.println("A message has arrived: " + message);
gameScreen.serverMessage = message;
}
} catch (EOFException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and the class is called when I hit "s" in the server or in the client, they both use the same class
public void sendTCPMessage(String message) {
try {
output.writeBytes(message);
output.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
If you want to read lines, you must write lines.
If you want to read with a BufferedReader, you should write with a BufferedWriter.
If you want to write with a DataOutputStream, you should read with a DataInputStream.

NullPointerException when receiving an array list over a socket

Trying to send an arrayList over a socket, get a null pointer exception at object input stream initialization (client).
Client:
try {
ObjectInputStream objIn = new ObjectInputStream(
Client.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
Server:
try {
ObjectOutputStream objOut = new ObjectOutputStream(
this.client.getOutputStream());
objOut.writeObject(library);
objOut.flush(); // added later, not helping
}
I've been trying to comunicate over sockets for two days now with almost no success. I have no idea what's going on. Ofc I plan to document myself better when I'll have more time but for now I'd really like to understand what is happening.
EDIT
public class Client {
private static int port = 6666;
private static Socket socket = null;
public Client (int port) {
Client.port = port;
}
public Client () {
}
public void establishConnection() {
try {
Client.socket = new Socket(InetAddress.getByName(null), Client.port);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Server:
public void start () {
(new Thread() {
public void run() {
try {
Server.socket = new ServerSocket(Server.portNumber);
while (!Server.stop) {
Socket client = Server.socket.accept();
(new HandleRequest (client)).start();
}
...............
public class HandleRequest extends Thread {
private Socket client = null;
private SQL sql_db = new SQL ();
public HandleRequest (Socket client) {
this.client = client;
}
#Override
public void run () {
try {
if (!this.sql_db.isConnected())
this.sql_db.connect();
if (this.client == null) {
System.out.println("Error: client does not exist, NO idea what's going on");
return;
}
ArrayList<Book> library = this.sql_db.getAllBooks();
try {
ObjectOutputStream objOut = new ObjectOutputStream(
this.client.getOutputStream());
objOut.writeObject(library);
objOut.flush();
} catch (Exception e) {
System.out.println("Server error in handling request for whole library!");
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
Because the NPE is on this line:
Client.socket.getInputStream());
there is only one thing that can cause it. It can't be Client, because that is static. It can't be getInputStream(), because that is a method, so it has to be socket that is causing the NPE.
On this line:
private static Socket socket = null;
you set socket to be null. The only place I see where you set it to be not null is in your .establishConnection() method, but I don't see where you call that method.
Therefore, your problem is most likely that you aren't calling the .establishConnection() method.
Is you establishConnection method called before
try {
ObjectInputStream objIn = new ObjectInputStream(
Client.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {
If not, your Client.socket is null and you need to initialize it. I.e. your code should look like this:
try {
Client c = new Client(1337);
c.establishConnection();
ObjectInputStream objIn = new ObjectInputStream(
c.socket.getInputStream()); // HERE
library = (ArrayList<Book>) objIn.readObject();
} catch (IOException e) {

Sign in button has no visible effect in a Java application

I have two applications, one is a server and the other is a client. At first, I run my server application. Then I will run the client application. When running the client application, a window will be shown to prompt for a username and password and if they were correct, another window will be shown. When I click on the “Sign In” button, nothing happens. What's wrong?
Main class in Server application:
public static void main(String[] args) {
System.out.println("Server is starting...");
ServerSocket server = null;
try {
server = new ServerSocket(5000);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Server is listening...");
while (true) {
try {
Socket socket = server.accept();
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
System.out.println("Client Connected...");
}
}
Client class which has a socket in it:
private static InformationClass info = new InformationClass();
private static Socket c;
static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
/**
* #param args the command line arguments
*/
public static void runAClient() {
try {
c = new Socket("localhost", 5000);
} catch (UnknownHostException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
public static void clienT(){
try {
BufferedReader read = new BufferedReader(new InputStreamReader(c.getInputStream()));
BufferedWriter write = new BufferedWriter(new OutputStreamWriter(c.getOutputStream()));
while (true) {
String string = reader.readLine();
write.write(string, 0, string.length());
write.newLine();
write.flush();
System.out.println(read.readLine());
}
} catch (Exception e) {
System.err.println(e);
}
}
public static boolean connected() {
boolean bool = false;
if (c.isConnected()) {
info.setSituation("Connected");
bool = true;
} else {
info.setSituation("disconnected");
bool = false;
}
return bool;
}
The main window in the client application, which I start after when I run the server application. A part of that is for the “Sign In” button.
private void submit() {
String id = idField.getText();
char[] pass1 = passField.getPassword();
String pass = new String(pass1);
if (id.equals("") || pass.equals("")) {
ErrorFrame frame = new ErrorFrame();
frame.setVisible(true);
} else {
boolean b = Manager.Test(id, pass);
if (b == true) {
Main.runAClient();
boolean boOl = Main.connected();
if(boOl==true){
this.setVisible(false);
ListFrame fRAme = new ListFrame(client);
fRAme.setVisible(true);
}
else{
JOptionPane.showConfirmDialog(this, "You couldn't connect successfully,please try again!","sign_In Problem",JOptionPane.ERROR_MESSAGE);
return;
}
} else {
JOptionPane.showConfirmDialog(this, "You have entered wrong datas,try it again");
return;
}
}
}
Have you tried stepping through your code using a debugger to work out precisely which line of code is not working correctly? Simply stating that "nothing happens" when you click on the sign-in button doesn't give us much to go on.
Are you sure your submit() method is called when you click 'Sign In' button?
Another thing, Main.RunAClient() never returns constantly asking user to enter a line in system console.

Categories