Read a message in Server from Client RMI - java

I have a the necessary RMI classes created, The client can send a message and it gets printed in the server window.
On the server i would like to read the message and for example if the message is equal to 100 then print out a message.
The problem being when i run the server i immediately get a null pointer exception. When i send the message 100 from the client to the server it prints the message but wont execute the if statement.
Interface:
import java.rmi.Remote;
import java.rmi.RemoteException;
public interface FileInterface extends Remote {
void message(String message) throws RemoteException;
}
Implementation:
import java.io.*;
import java.rmi.*;
import java.rmi.server.UnicastRemoteObject;
public class FileImpl extends UnicastRemoteObject implements FileInterface {
private String name;
public FileImpl(String s) throws RemoteException {
super();
name = s;
}
public void message(String message) throws RemoteException{
System.out.println(message);
}
} catch(Exception e) {
System.err.println("FileServer exception: "+ e.getMessage());
e.printStackTrace();
return(null);
}
}
}
Client:
import java.io.*;
import java.rmi.*;
import javax.swing.*;
import java.util.*;
import java.awt.*;
public class FileClient{
public static boolean loggedIn = false;
public static void main(String argv[]) {
try {
int RMIPort;
String hostName;
InputStreamReader is = new InputStreamReader(System.in);
BufferedReader br = new BufferedReader(is);
System.out.println("Enter the RMIRegistry host namer:");
hostName = br.readLine();
if( hostName.length() == 0 ) // if user did not enter a name
hostName = "localhost"; // use the default host name
System.out.println("Enter the RMIregistry port number:");
String portNum = br.readLine();
if( portNum.length() == 0 )
portNum = "1097"; // default port number
RMIPort = Integer.parseInt(portNum);
String registryURL = "rmi://" + hostName+ ":" + portNum + "/FileServer";
// find the remote object and cast it to an interface object
FileInterface fi = (FileInterface) Naming.lookup(registryURL);
System.out.println("Lookup completed " );
//System.out.println("File " + argv[0] + " Transfered" );
// invoke the remote method
boolean done = false;
//file.getName()
while( !done ) {
System.out.println("Enter Code: 100 = Login, 200 = Upload, 300 = Download, 400 = Logout: ");
String message = br.readLine();
boolean messageOK = false;
if( message.equals("100") ) {
messageOK = true;
System.out.println("Enter T-Number: (Use Uppercase 'T')");
String login = br.readLine();
if( login.charAt(0) == 'T' ) {
loggedIn = true;
fi.message("100");
System.out.println("Login Successful");
continue;
} else {
System.out.println("Login Error");
continue;
}
}
}
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Server:
import java.io.*;
import java.rmi.*;
public class FileServer {
public static void main(String argv[]) {
if(System.getSecurityManager() == null) {
System.setSecurityManager(new RMISecurityManager());
}
try {
FileInterface fi = new FileImpl("FileServer");
Naming.rebind("//localhost:1097/FileServer", fi);
System.out.println("Server Started...");
boolean done = false;
while( !done ) {
if ((msg.trim()).equals("100")) {
System.out.println("message recieved: 100 logged in");
} else {
System.out.println("Login Error");
}
}
} catch(Exception e) {
System.out.println("FileServer: "+e.getMessage());
e.printStackTrace();
}
}
}
Any help here would be appreciated.

Related

How can I make my server recognize more than 1 user's login info in java?

Now I do realize there are lots of the same question but even after reading the answers I seem not to undertsand. So here is the code and I'll explain the problem.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Objects;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class Server implements Runnable {
String firstName;
String lastName;
String password;
private ArrayList<ConnectionHandler> connections;
private ServerSocket server;
private boolean done;
private ExecutorService pool;
public Server() {
connections = new ArrayList<>();
done = false;
}
#Override
public void run() {
try {
server = new ServerSocket(9999);
pool = Executors.newCachedThreadPool();
while (!done) {
Socket client = server.accept();
ConnectionHandler handler = new ConnectionHandler((client));
connections.add(handler);
pool.execute(handler);
}
} catch (Exception e) {
shutdown();
}
}
public void shutdown() {
try {
done = true;
pool.shutdown();
if (!server.isClosed()) {
server.close();
}
for (ConnectionHandler ch : connections) {
ch.shutdown();
}
} catch (IOException e) {
// ignore
}
}
class ConnectionHandler implements Runnable {
private Socket client;
private BufferedReader in;
private PrintWriter out;
public void broadcast(String message) {
for (ConnectionHandler ch : connections) {
if (ch != null) {
ch.sendMessage(message);
}
}
}
public ConnectionHandler(Socket client) {
this.client = client;
}
#Override
public void run() {
try {
out = new PrintWriter((client.getOutputStream()), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
out.println("To register type 1,to sign in type 2");
//TODO:for loop so only answer is 1 or 2
String message = in.readLine();
switch (message) {
case "1":
out.println("In order to register please enter your first and last name then set a password.");
out.println("Enter first name:");
firstName = in.readLine();
out.println("Enter last name:");
lastName = in.readLine();
out.println("Finally please set a password.");
password = in.readLine();
//TODO: add parameters for passcode
out.println("Now please type 2 to login");
message = in.readLine();
if (message.equals("2")) {
//TODO: copy paste from line 104-x
}
case "2":
out.println("Please enter your first name:");
String messageLogInFN= in.readLine();
out.println("Please enter your last name:");
String messageLogInLN = in.readLine();
out.println("Enter your password:");
String messageLogInPass = in.readLine();
boolean adminAccount = (messageLogInFN.equals("admin") && messageLogInLN.equals("admin") && messageLogInPass.equals("admin123cat"));
if (adminAccount) {
//TODO: add admin permissions
}
boolean Authentication = ((messageLogInFN.equals(firstName) && messageLogInLN.equals(lastName) && messageLogInPass.equals(password)));
if (Authentication) {
out.println("Welcome " + firstName + " " + lastName + "!");
System.out.println(firstName + " " + lastName + " has logged in." );
} else
out.println("Your name or password incorrect!");
}
} catch (IOException e) {
shutdown();
}
}
public void sendMessage(String message) {
out.println(message);
}
public void shutdown() {
try {
in.close();
out.close();
if (!client.isClosed()) {
client.close();
}
} catch (IOException e) {
//ignore
}
}
}
public static void main(String[] args) {
Server server = new Server();
server.run();
}
So I am learning java and saw a tutorial on youtube for a chat room, I programed it following the tutorial, and then I wanted to have a chat room with accounts so I got to coding. Now here is the thing even though I am able to have several devices connected to the server when 2 accounts register the server forgets the first one so there can only be 1 account at the same time. What I am trying to do is have an account system where everyone has their own account that they log in with their first name, last name and passwords. But it doesnt seem to work. How can I make it so that the server doesn't forget all accounts except for the last one that registered?
Edit: Here is the client code if it helps.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
public class Client implements Runnable {
private boolean done;
private Socket client;
private BufferedReader in;
private PrintWriter out;
#Override
public void run() {
try {
client = new Socket("127.0.0.1", 9999);
out = new PrintWriter((client.getOutputStream()), true);
in = new BufferedReader(new InputStreamReader(client.getInputStream()));
InputHandler inHandler = new InputHandler();
Thread t = new Thread(inHandler);
t.start();
String inMessage;
while ((inMessage = in.readLine()) != null) {
System.out.println(inMessage);
}
} catch (IOException e) {
shutdown();
}
}
public void shutdown() {
done = true;
try {
in.close();
out.close();
if(!client.isClosed()) {
client.close();
}
} catch (IOException e) {
//ignore
}
}
class InputHandler implements Runnable {
#Override
public void run() {
try {
BufferedReader inReader = new BufferedReader(new InputStreamReader(System.in));
while (!done) {
String message = inReader.readLine();
if(message.equals("/quit")) {
out.println(message);
inReader.close();
shutdown();
} else {
out.println(message);
}
}
} catch (IOException e) {
shutdown();
}
}
}
public static void main(String[] args) {
Client client = new Client();
client.run();
}
}
Also as I said most of this isnt my code and I followed a yt tutorial.

FTPSClient throw exception javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake

i need help i'm trying to create the connection with the FTP'Server where i upload my file.
i'm using below dependency with java jdk1.8.0_45. when i run my code it's make connection and also login but when i try to upload file it's throw Exception and upload empty file
Exception in thread "main" javax.net.ssl.SSLHandshakeException: Remote host closed connection during handshake
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:980)
at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java:1363)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1391)
at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:1375)
at org.apache.commons.net.ftp.FTPSClient._openDataConnection_(FTPSClient.java:619)
at org.apache.commons.net.ftp.FTPClient._storeFile(FTPClient.java:633)
at org.apache.commons.net.ftp.FTPClient.__storeFile(FTPClient.java:624)
at org.apache.commons.net.ftp.FTPClient.storeFile(FTPClient.java:1976)
at org.quorum.appnexusutility.transfer.TransferManager.uploadFile(TransferManager.java:176)
at org.quorum.appnexusutility.transfer.TransferManager.pushFile(TransferManager.java:220)
at org.quorum.appnexusutility.transfer.TransferManager.main(TransferManager.java:233)
Caused by: java.io.EOFException: SSL peer shut down incorrectly
at sun.security.ssl.InputRecord.read(InputRecord.java:505)
at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java:961)
... 10 more
Dependency
<dependency>
<groupId>commons-net</groupId>
<artifactId>commons-net</artifactId>
<version>3.3</version>
</dependency>
Below code i change the host may not work for you
package org.quorum.appnexusutility.transfer;
import org.apache.commons.lang.RandomStringUtils;
import org.apache.commons.net.PrintCommandListener;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPReply;
import org.apache.commons.net.ftp.FTPSClient;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.Date;
import java.util.Locale;
#Component
#Scope("prototype")
public class TransferManager {
public Logger logger = LogManager.getLogger(TransferManager.class);
// SSL/TLS
private final Integer TENSECONDS = 10*1000; // 10 second
private final String protocol = "TLS";//"TLS";
private Boolean isLogin = false;
private Boolean isUpload = false;
private String directoryPath;
private String host;
private Integer port;
private String user;
private String password;
private FTPSClient ftpsClient;
public TransferManager() { }
public String getHost() { return host; }
public TransferManager setHost(String host) {
this.host = host;
return this;
}
public Integer getPort() { return port; }
public TransferManager setPort(Integer port) {
this.port = port;
return this;
}
public String getUser() { return user; }
public TransferManager setUser(String user) {
this.user = user;
return this;
}
public String getPassword() { return password; }
public TransferManager setPassword(String password) {
this.password = password;
return this;
}
public String getDirectoryPath() { return directoryPath; }
public void setDirectoryPath(String directoryPath) {
this.directoryPath = directoryPath;
}
public void open() throws IOException {
//System.setProperty("jdk.tls.useExtendedMasterSecret", "false");
//this.ftpsClient = new SSLSessionReuseFTPSClient();
//ftpsClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out), true));
if(this.port > 100) {
this.ftpsClient = new FTPSClient(this.protocol, true);
} else {
this.ftpsClient = new FTPSClient(false);
}
this.ftpsClient.setControlKeepAliveTimeout(TENSECONDS);
this.showServerReply(this.ftpsClient);
logger.info("FTP :- Connection try :- IP :- (" + this.host + ") , Port :- " + this.port + " Start");
this.ftpsClient.connect(this.host, this.port);
this.ftpsClient.addProtocolCommandListener(new PrintCommandListener(new PrintWriter(System.out)));
logger.info("FTP :- Connection try :- IP :- (" + this.host + ") , Port :- " + this.port + " Done");
int reply = this.ftpsClient.getReplyCode();
logger.info("FTP :- Connection Code :- " + reply);
if(!FTPReply.isPositiveCompletion(reply)) {
this.ftpsClient.disconnect();
throw new IOException("Exception in connecting to FTP Server");
}
this.isLogin = this.ftpsClient.login(user, password);
this.showServerReply(this.ftpsClient);
logger.info("FTP :- Login Status :- " + this.isLogin);
}
private Boolean makeDirectory() throws IOException {
Boolean isDirectoryCreate = false;
if(this.isLogin && this.directoryPath != null) {
isDirectoryCreate = this.ftpsClient.makeDirectory(this.directoryPath);
this.showServerReply(this.ftpsClient);
if (isDirectoryCreate) {
logger.info("Successfully created directory: " + this.directoryPath);
} else {
logger.info("Failed to create directory. See server's reply.");
}
}
return isDirectoryCreate;
}
// if returns 250, folder exists and if returned 550 folder does not exist***
private Boolean isDirectoryExist() throws IOException {
if(this.ftpsClient.cwd(this.directoryPath) == 550) {
logger.info("Directory Not Exist");
return false;
} else {
logger.info("Directory Exist");
return true;
}
}
// upload process
public Boolean uploadFile(File file) throws Exception {
if(this.isLogin && this.directoryPath != null) {
if(!this.isDirectoryExist()) {
// call when not exist
this.makeDirectory();
}
this.ftpsClient.enterLocalPassiveMode();
this.ftpsClient.execPBSZ(0);
this.ftpsClient.execPROT("P");
this.ftpsClient.setFileType(FTP.BINARY_FILE_TYPE);
// only the text file can be upload
//this.ftpsClient.setFileType(FTP.TELNET_TEXT_FORMAT);
this.ftpsClient.changeWorkingDirectory(this.getDirectoryPath());
logger.info("Current Directory " + this.ftpsClient.printWorkingDirectory());
FileInputStream fileInputStream = new FileInputStream(file);
String filePath = RandomStringUtils.randomAlphanumeric(8)+".txt";
logger.info("Final Path :- " + filePath);
//this.isUpload =
this.ftpsClient.storeFile(filePath, fileInputStream);
if(this.isUpload) {
logger.info("The file is uploaded successfully.");
}
// close the stream which use to store the file
fileInputStream.close();
}
return this.isUpload;
}
// connection close for client
public void close() throws IOException {
if (this.ftpsClient.isConnected()) {
this.ftpsClient.logout();
this.ftpsClient.disconnect();
}
}
public String getDirectoryPathRandom() {
Date date = new Date();
LocalDate localDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
int year = localDate.getYear();
int month = localDate.getMonthValue();
int day = localDate.getDayOfMonth();
int hours = date.getHours();
logger.info("Year :- (" + year + ") Month :- (" + month + ") Day :- (" + day + ") Hours :- (" + hours + ")");
return year + "/"+ month + "/" + day + "/" + hours;
}
private void showServerReply(FTPSClient ftpsClient) {
String[] replies = ftpsClient.getReplyStrings();
if (replies != null && replies.length > 0) {
for (String aReply : replies) {
logger.info("SERVER: " + aReply);
}
}
}
// this method use to push the file from 1 server to other server
public static void pushFile(String host, int port, String user, String password, File file) throws Exception {
TransferManager transferManager = new TransferManager().setHost(host).setPort(port).setUser(user).setPassword(password);
// we push the fiel on the base of yyyy/mm/dd/hr
// first check if the dir exist then no need to create the directory
transferManager.setDirectoryPath(transferManager.getDirectoryPathRandom());
transferManager.open(); // open connection
transferManager.uploadFile(file); // file
transferManager.close(); // close connection
}
//======================FTP=========================
//FTP URL: ftp.dlptest.com or ftp://ftp.dlptest.com/
//FTP User: dlpuser#dlptest.com
//Password: bbCKucPzfr4b9YXUY7tvsNKyh
public static void main(String args[]) throws Exception {
pushFile("ftps.xyzserver.com", 990, "macak", "Go447641", new File("C:\\Users\\Nabeel.Ahmed\\Desktop\\Study-Pending\\Detail Document.txt"));
}
}
It seems to be the problem with SSL/TLS protocol version issue. Go through the following post SSL peer shut down incorrectly in Java You should get the answer.
Can you try to replace the following line
private final String protocol = "TLS";//"TLS";
with
private final String protocol = "TLSv1.1";
All after lot of search and finally found the solution by reuse the method of prepareDataSocket here the code.
import org.apache.commons.net.ftp.FTPSClient;
import javax.net.ssl.SSLSession;
import javax.net.ssl.SSLSessionContext;
import javax.net.ssl.SSLSocket;
import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.net.Socket;
import java.util.Locale;
public class ModifiedFTPSClient extends FTPSClient {
public ModifiedFTPSClient() {
super("TLS", false);
}
public ModifiedFTPSClient(boolean isImplicit) {
super("TLS", isImplicit);
}
#Override
protected void _prepareDataSocket_(final Socket socket) throws IOException {
if (socket instanceof SSLSocket) {
final SSLSession session = ((SSLSocket) _socket_).getSession();
if (session.isValid()) {
final SSLSessionContext context = session.getSessionContext();
try {
final Field sessionHostPortCache = context.getClass().getDeclaredField("sessionHostPortCache");
sessionHostPortCache.setAccessible(true);
final Object cache = sessionHostPortCache.get(context);
final Method method = cache.getClass().getDeclaredMethod("put", Object.class, Object.class);
method.setAccessible(true);
method.invoke(cache, String.format("%s:%s", socket.getInetAddress().getHostName(), String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT), session);
method.invoke(cache, String.format("%s:%s", socket.getInetAddress().getHostAddress(), String.valueOf(socket.getPort())).toLowerCase(Locale.ROOT), session);
} catch (NoSuchFieldException e) {
throw new IOException(e);
} catch (Exception e) {
throw new IOException(e);
}
} else {
throw new IOException("Invalid SSL Session");
}
}
}
Above Question Class TransferManager replace the class like this
private String user;
private String password;
private ModifiedFTPSClient ftpsClient;
Above Question Class TransferManager replace the value in open() method
if(this.port > 100) {
this.ftpsClient = new ModifiedFTPSClient(true); // fro ftps
} else {
this.ftpsClient = new ModifiedFTPSClient(); // fro ftp
}

Java showInputDialog when data not correct

import javax.swing.*;
import java.io.Serializable;
import java.rmi.registry.LocateRegistry;
import java.rmi.registry.Registry;
public class Server implements Serializable{
public static void main(String[] args) {
String test1= JOptionPane.showInputDialog(null,"Port(0-65535):","Port",JOptionPane.QUESTION_MESSAGE);
int portnumber = tryParse(test1);
if (portnumber !=0) {
try {
Registry reg = LocateRegistry.createRegistry(portnumber); //Creates and exports a Registry instance on the local host that accepts requests
RmiImplementation imp = new RmiImplementation("C://ServerStorage");
reg.bind("remoteObject", imp);
System.out.println("Server is ready.");
System.out.println(portnumber);
} catch (Exception e) {
System.out.println("Server failed: " + e);
}
}
}
private static Integer tryParse(String text) {
try {
return Integer.parseInt(text);
} catch (Exception e) {
return 0;
}
}
}
The above code helps me to set up my file server.
when the application is run, the dialog port number is requested.
If I type letters instead of numbers the program stops running, but I want it to continue and show me the dialog again.
Try with a do-while,
int portnumber = 0;
do {
String text= JOptionPane.showInputDialog(null,"Port(0-65535):","Port",JOptionPane.QUESTION_MESSAGE);
portnumber = tryParse(text);
}while(portnumber==0);

java.util.NoSuchElementException: No line found error java

Keep getting this error
"java.util.NoSuchElementException: No line found error java"
and searched through code so many times and cant see to find problems heres my files can anyone help?
Am currently doing this as an assignment and am trying to transfer it from unthreaded to threaded and in the process came up with this error!!
This is the Client class
package Client;
import core.Email;
import core.EmailServiceDetails;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Date;
import java.util.InputMismatchException;
import java.util.Scanner;
public class EmailClient {
public static void main(String[] args) {
try
{
// Step 1 (on consumer side) - Establish channel of communication
Socket dataSocket = new Socket("localhost", EmailServiceDetails.LISTENING_PORT);
// Step 3) Build output and input objects
OutputStream out = dataSocket.getOutputStream();
PrintWriter output = new PrintWriter(new OutputStreamWriter(out));
InputStream in = dataSocket.getInputStream();
Scanner input = new Scanner(new InputStreamReader(in));
Scanner keyboard = new Scanner(System.in);
String message = "";
while(!message.equals(EmailServiceDetails.END_SESSION))
{
displayMenu();
int choice = getNumber(keyboard);
String response = "";
if(choice >=0 && choice < 3)
{
switch (choice)
{
case 0:
message = EmailServiceDetails.END_SESSION;
// Send message
output.println(message);
output.flush();
response = input.nextLine();
if(response.equals(EmailServiceDetails.SESSION_TERMINATED))
{
System.out.println("Session ended.");
}
break;
case 1:
message = sendEmail(keyboard);
// Send message
output.println(message);
output.flush();
// Get response
response = input.nextLine();
if(response.equals(EmailServiceDetails.SUCCESSFUL_ADD))
{
System.out.println("Email sent successfully");
}
else if(response.equals(EmailServiceDetails.UNSUCCESSFUL_ADD))
{
System.out.println("Sorry, the email could not be sent at this time.");
}
break;
case 2:
message = viewUnread(keyboard);
// Send message
output.println(message);
output.flush();
// Get response
response = input.nextLine();
if(response.equals(EmailServiceDetails.NO_UNREAD))
{
System.out.println("No unread mails found for that account.");
}
else
{
ArrayList<Email> unreadMails = EmailServiceDetails.parseEmailList(response);
System.out.println("Unread Emails:");
for(Email e: unreadMails)
{
System.out.println(e);
}
}
break;
}
if(response.equals(EmailServiceDetails.UNRECOGNISED))
{
System.out.println("Sorry, that request cannot be recognised.");
}
}
else
{
System.out.println("Please select an option from the menu");
}
}
System.out.println("Thank you for using the Email system.");
dataSocket.close();
}catch(Exception e)
{
System.out.println("An error occurred: " + e.getMessage());
e.printStackTrace();
}
}
public static void displayMenu()
{
System.out.println("0) Exit");
System.out.println("1) Send an email");
System.out.println("2) View all unread mails");
}
public static int getNumber(Scanner keyboard)
{
boolean numberEntered = false;
int number = 0;
while(!numberEntered)
{
try{
number = keyboard.nextInt();
numberEntered = true;
}
catch(InputMismatchException e)
{
System.out.println("Please enter a number.");
keyboard.nextLine();
}
}
keyboard.nextLine();
return number;
}
public static String sendEmail(Scanner keyboard)
{
System.out.println("Please enter the sender of this email:");
String sender = keyboard.nextLine();
// Get recipient information
String anotherRecipient = "Y";
ArrayList<String> recipients = new ArrayList();
while(anotherRecipient.equalsIgnoreCase("Y"))
{
System.out.println("Enter the recipient's email address:");
String recipient = keyboard.nextLine();
recipients.add(recipient);
System.out.println("Would you like to add another recipient? ('Y' for yes and 'N' for no)");
anotherRecipient = keyboard.nextLine();
}
System.out.println("Please enter the email subject:");
String subject = keyboard.nextLine();
System.out.println("Please enter the message body:");
String body = keyboard.nextLine();
// Get attachment information
ArrayList<String> attachments = new ArrayList();
System.out.println("Would you like to enter an attachment ('Y' to add and 'N' to continue)");
String anotherAttachment = keyboard.nextLine();
while(anotherAttachment.equalsIgnoreCase("Y"))
{
System.out.println("Enter the attachment information:");
String attachment = keyboard.nextLine();
attachments.add(attachment);
System.out.println("Would you like to add another attachment? ('Y' for yes and 'N' to Continue)");
anotherAttachment = keyboard.nextLine();
}
long timestamp = new Date().getTime();
String response = null;
Email e = null;
if(attachments.size() > 0)
{
e = new Email(sender, recipients, subject, body, timestamp, attachments);
}
else
{
e = new Email(sender, recipients, subject, body, timestamp);
}
response = EmailServiceDetails.ADD_MAIL + EmailServiceDetails.COMMAND_SEPARATOR + EmailServiceDetails.formatEmail(e);
return response;
}
public static String viewUnread(Scanner keyboard)
{
System.out.println("Please enter the name of the email account you wish to see unread mail for:");
String recipient = keyboard.nextLine();
String response = EmailServiceDetails.VIEW_UNREAD + EmailServiceDetails.COMMAND_SEPARATOR + recipient;
return response;
}
}
--------------------------------------------------------------------------------
This is Server
---------------
package Server;
import Server.Commands.Command;
import core.EmailServiceDetails;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Scanner;
public class EmailServer {
public static void main(String[] args) {
try{
// Set up a connection socket for other programs to connect to
ServerSocket listeningSocket = new ServerSocket(EmailServiceDetails.LISTENING_PORT);
// Create the list of emails to be stored and worked with
EmailStore emails = new EmailStore();
boolean continueRunning = true;
int threadCount = 0;
while(continueRunning)
{
// Step 2) wait for incoming connection and build communications link
Socket dataSocket = listeningSocket.accept();
threadCount++;
System.out.println("The server has now accepted " + threadCount + " clients");
// Step 3) Build thread
// Thread should be given:
// 1) a group to be stored in
// 2) a name to be listed under
// 3) a socket to communicate through
// 4) Any extra information that should be shared
EmailThread newClient = new EmailThread (emails, dataSocket.getInetAddress()+"", dataSocket,threadCount);
newClient.start();
}
listeningSocket.close();
}
catch(Exception e)
{
System.out.println("An error occurred: " + e.getMessage());
}
}
}
--------------------------------------------------------------------------------
This is ServerThread
---------------
package Server;
import Server.Commands.Command;
import Server.EmailStore;
import core.EmailServiceDetails;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Date;
import java.util.Scanner;
/**
*
* #author User
*/
public class EmailThread extends Thread {
private Socket dataSocket;
private Scanner input;
private PrintWriter output;
private int number;
private EmailStore emails;
public EmailThread(EmailStore emails,String name, Socket dataSocket, int number) {
try {
// Save the data socket used for communication between the thread and the Client
this.dataSocket = dataSocket;
// Save the id of the thread to identify output
// Save the id of the thread to identify output
this.number = number;
input = new Scanner(new InputStreamReader(this.dataSocket.getInputStream()));
// Create the stream for writing to the Client
output = new PrintWriter(this.dataSocket.getOutputStream(), true);
} catch (IOException e) {
System.out.println("An exception occurred while setting up connection links for a thread: " + e.getMessage());
}
}
#Override
public void run() {
{
String incomingMessage = "";
String response;
try {
while (!incomingMessage.equals(EmailServiceDetails.END_SESSION)) {
// Wipe the response to make sure we never use an old value
response = null;
// take in information from the client
incomingMessage = input.nextLine();
System.out.println("Received message: " + incomingMessage);
// Break up information into components
String[] components = incomingMessage.split(EmailServiceDetails.COMMAND_SEPARATOR);
// Confirm that the command was correctly formatted
// Did it include more than just the command text?
if (components.length > 1) {
CommandFactory factory = new CommandFactory();
// Figure out which command was sent by the client
// I.e. what does the client want to do?
Command command = factory.createCommand(components[0]);
// Take the remaining text the client sent (i.e. all the information provided)
// and execute the requested action (e.g. store the new mail, get all sent mails etc)
response = command.createResponse(components[1], emails);
} else if (components[0].equals(EmailServiceDetails.END_SESSION)) {
response = EmailServiceDetails.SESSION_TERMINATED;
} else {
// If information was missing, set the response to inform the
// client that the command wasn't recognised
response = EmailServiceDetails.UNRECOGNISED;
}
// Send back the computed response
output.println(response);
output.flush();
}
} catch (Exception e) {
System.out.println("An exception occurred while communicating with client #" + number + ": " + e.getMessage());
} finally {
try {
// Shut down connection
System.out.println("\n* Closing connection with client #" + number + "... *");
dataSocket.close();
} catch (IOException e) {
System.out.println("Unable to disconnect: " + e.getMessage());
System.exit(1);
}
}
}
}
}
--------------------------------------------------------------------------------
This is EmailStore
---------------
package Server;
import core.Email;
import java.util.ArrayList;
import java.util.stream.Collectors;
public class EmailStore
{
private ArrayList<Email> emailList = new ArrayList();
public boolean addMail(Email newEmail)
{
return emailList.add(newEmail);
}
public boolean removeMail(Email mailToBeDeleted)
{
return emailList.remove(mailToBeDeleted);
}
public ArrayList<Email> findEmailByRecipient(String recipient)
{
ArrayList<Email> results = new ArrayList();
results = (ArrayList<Email>) emailList.stream()
// Find all emails whose recipients list contents the specified recipient
.filter(email -> email.getRecipients().contains(recipient))
// Collect the results back into a List (this does not return an ArrayList, so need to cast)
.collect(Collectors.toList());
return results;
}
public ArrayList<Email> findEmailBySender(String sender)
{
ArrayList<Email> results = new ArrayList();
results = (ArrayList<Email>) emailList.stream()
// Find all emails matching the specified sender
.filter(email -> email.getSender().equals(sender))
// Collect the results back into a List (this does not return an ArrayList, so need to cast)
.collect(Collectors.toList());
return results;
}
// Methods to mark emails as read
// Provide a version that marks multiple mails as read AND a version that
// marks a single email as read
public void markMultipleAsRead(ArrayList<Email> emails)
{
for(Email e : emails)
{
markAsRead(e);
}
}
public void markAsRead(Email e)
{
int index = emailList.indexOf(e);
if(index != -1)
{
Email storedMail = emailList.get(index);
storedMail.markAsRead(true);
}
}
// Methods to mark emails as spam
// Provide a version that marks multiple mails as spam AND a version that
// marks a single email as spam
public void markAsSpam(Email e)
{
int index = emailList.indexOf(e);
if(index != -1)
{
Email storedMail = emailList.get(index);
storedMail.markAsSpam(true);
}
}
public void markMultipleAsSpam(ArrayList<Email> emails)
{
for(Email e : emails)
{
markAsSpam(e);
}
}
public ArrayList<Email> findUnreadEmailByRecipient(String recipient)
{
ArrayList<Email> results = new ArrayList();
results = (ArrayList<Email>) emailList.stream()
// Find all emails whose recipients list contents the specified recipient AND the email is not unread
.filter(email -> email.getRecipients().contains(recipient) && !email.isRead())
// Collect the results back into a List (this does not return an ArrayList, so need to cast)
.collect(Collectors.toList());
return results;
}
}
-------
Help Appreciated
-
----------
Help would be great appreciated as the frustration levels are at a high!!
This answer is a wild guess but in case 1 of the switch statement of the main method you are calling the input.nextLine() scanner which it might not contain information at that time. It is possible that you have to check if data arrived by using the hasNext() method first.
Also in the last method when you are collecting the email classes you don't really need to cast. It can be done like this:
results = emailList.stream()
.filter(email -> email.getRecipients().contains(recipient) && !email.isRead())
.collect(Collectors.toCollection(ArrayList::new));

Custom Java Socket class

This is my first time messing around with Sockets, and it was working up until now. Basically, I have a custom ServerSocket class named Server and a custom Socket class named Client.
When Client tries to connect to Server, Server performs a little check to make sure it is actually Client that it trying to make the connection, and not some other socket, because Client has certain methods that I need.
However, this check always returns false. Here is my Server connection code:
package me.eli.server;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.HashMap;
import java.util.Map;
import me.eli.client.Client;
public class Server extends ServerSocket {
private final Map<Client, IOPair> clients = new HashMap<Client, IOPair>();
public Server(final int port) throws IOException {
super(port);
System.out.println("Server started on " + getLocalPort() + "... Waiting for client!");
}
public Client waitOnClient() throws IOException {
final Socket generalClient = accept();
final Client client;
if(!(generalClient instanceof Client)) {
client = null;
PrintWriter out = new PrintWriter(generalClient.getOutputStream(), true);
out.println("Access denied: " + generalClient.getClass().getSimpleName());
log("Invalid client: " + generalClient.getClass().getName() + " (" + generalClient.getInetAddress().getHostAddress() + ")");
out.close();
} else
client = (Client) generalClient;
if(client == null)
return null;
client.setServer(this);
BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
PrintWriter out = new PrintWriter(client.getOutputStream(), true);
broadcast(client.getName() + " has joined.");
clients.put(client, new IOPair(in, out));
System.out.println("Client (" + client.getName() + ") connected from " + client.getInetAddress().getHostAddress());
out.println("Connected! Welcome to the server.");
return client;
}
#Override
public void close() throws IOException {
for(Client c : getClients())
kick(c, "Server closed");
super.close();
}
public void kick(Client c, String reason) {
try {
c.message("disconnect", reason);
c.close();
} catch(IOException e) {
log("Failed to kick " + c.getName() + ": " + e.getMessage());
c.message("error", "Failed to disconnect");
}
}
public void log(String message) {
getServerOut().println(message);
}
public void log(String source, String message) {
log("<" + source + "> " + message);
}
public void broadcast(String message) {
log("broadcast", message);
for(Client c : getClients())
c.message("broadcast", message);
}
public Client[] getClients() {
return clients.keySet().toArray(new Client[clients.keySet().size()]);
}
public BufferedReader getClientIn(Client c) {
return clients.get(c).getIn();
}
public PrintWriter getClientOut(Client c) {
return clients.get(c).getOut();
}
public InputStream getServerIn() {
return System.in;
}
public PrintStream getServerOut() {
return System.out;
}
public static boolean isServerRunningOn(final int port) {
try {
new ServerSocket(port).close();
return false;
} catch(IOException e) {
return true;
}
}
}
And here is my Client connection code:
package me.eli.client;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.io.PrintWriter;
import java.net.Socket;
import me.eli.server.IOPair;
import me.eli.server.Server;
public class Client extends Socket {
private Server server;
private final IOPair serverio;
private final String name;
public Client(final String host, final int port) throws IOException {
this(host, port, "Guest-" + (int) (Math.random() * 10000));
}
public Client(final String host, final int port, final String name) throws IOException {
super(host, port);
System.out.println("Connected to server on " + host + ":" + port);
BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
PrintWriter out = new PrintWriter(getOutputStream(), true);
this.name = name;
this.serverio = new IOPair(in, out);
String input;
if((input = in.readLine()) != null)
System.out.println("<Welcome message> " + input);
out.println("Yay! I'm connected!");
}
#Override
public synchronized void close() throws IOException {
if(serverio != null) {
if(server != null)
server.broadcast(getName() + " has disconnected.");
message("server", "Disconnected.");
super.close();
serverio.getIn().close();
serverio.getOut().close();
} else
super.close();
}
public void message(String source, String message) {
getClientOut().println("<" + source + "> " + message);
}
public String getName() {
return name;
}
public void setServer(Server server) {
this.server = server;
}
public Server getServer() {
return server;
}
public BufferedReader getServerIn() {
return serverio.getIn();
}
public PrintWriter getServerOut() {
return serverio.getOut();
}
public InputStream getClientIn() {
return System.in;
}
public PrintStream getClientOut() {
return System.out;
}
}
I'm not the most experienced with networking, but this confuses me because I do indeed connect with my Client class. Thanks in advance!
Server performs a little check to make sure it is actually Client that it trying to make the connection
Impossible and nonsensical. The Client class is at the other end of the connection. It is not magically transmitted to your accept() method. If you want to validate your client you will have to build something into your application protocol.
Notes:
Calling Client.setServer() is similarly futile. It is not magically transmitted to the client.
It is possible to get your ServerSocket-derived class to create Client objects instead of Socket objects in its accept() method, but that doesn't actually solve the issue you're trying to solve.

Categories