java.io.IOException: Premature EOF while reading serialized object - java

I am working on a homework which i have to send back and forth an object in serialized mode.I have a Client3.java file which sends an object to Server3.java.And Server3.java do the exact same thing.But when i try to read the object in Client3 he throws a java.io.IOException: Premature EOF error.From an extensive search i found that my program runs faster than the InputStream reading but i dont know how to fix this
here my 2 files
package server3;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.net.HttpURLConnection;
import java.net.URL;
public class Client3 {
public static void main(String[] args) throws Exception {
try {
URL url = new URL("http://localhost:3333");
HttpURLConnection s = (HttpURLConnection) url.openConnection();
s.setDoOutput(true);
s.setDoInput(true);
s.setRequestMethod("POST");
s.setUseCaches(false);
//here we send an serialized object
Send obj = new Send();
ObjectOutputStream objOut = new
ObjectOutputStream(s.getOutputStream());
objOut.writeObject(obj);
/*********this is the chunk of code that makes the error*****************/
//here we read the serialized object
InputStream in = s.getInputStream();
ObjectInputStream ios = new ObjectInputStream(in);
SendResponse oin = (SendResponse) ios.readObject();
String gabim=oin.getGabim();
String gabimNr =oin.getGabimNr();
System.out.println(gabim);
System.out.println(gabimNr);
ios.close();
s.disconnect();
/***************************************************************************/
//catch all the possible errors
} catch (IOException ex) {
System.err.println("Gabim ne klient"+ex);
ex.printStackTrace();
}
}
}
class Send implements Serializable {
// the object to be send to the server
private static final long serialVersionUID = 1L;
int id = 1;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public int getPaid() {
return paid;
}
public void setPaid(int paid) {
this.paid = paid;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
int amount = 2000;
int paid = 800;
String name = "Andi Domi";
}
And here it is the Server3.java file
package server3;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.io.Serializable;
import java.net.InetSocketAddress;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import com.sun.net.httpserver.HttpExchange;
import com.sun.net.httpserver.HttpHandler;
import com.sun.net.httpserver.HttpServer;
public class Server3 {
public static void main(String[] args) throws Exception {
//create the server
HttpServer server = HttpServer.create(new InetSocketAddress(3333), 0);
server.createContext("/", new MyHandler());
server.setExecutor(null); // creates a default executor
server.start();
}
static class MyHandler implements HttpHandler {
public void handle(HttpExchange t) throws IOException {
/*******we start to read the object send from the client here*******/
//create the sream
ObjectInputStream ios = new ObjectInputStream(t.getRequestBody());
//variables we need to connect to the database
final String url = "jdbc:mysql://localhost/httpServer";
final String user = "root";
final String password = "";
try {
//create the object to be read
Send oin = (Send) ios.readObject();
int id = oin.getId();
String emri = oin.getName();
int amount = oin.getAmount();
int paid = oin.getPaid();
//jdbc try
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection(url, user,password);
//insert values into the first table
PreparedStatement s = con
.prepareStatement("INSERT INTO person(ID,Name,Amount,Paid) VALUES (?,?,?,?)");
s.setInt(1, id);
s.setString(2, emri);
s.setInt(3, amount);
s.setInt(4, paid);
s.executeUpdate();
//read the values from a table and add them to an array list
ResultSet rs = s.executeQuery("SELECT * from personat ORDER BY ID");
ArrayList<Personat> perList = new ArrayList<Personat>();
if (rs != null) {
while (rs.next()) {
Personat per = new Personat();
per.setID(rs.getInt("ID"));
per.setName(rs.getString("Name"));
per.setAmount(rs.getInt("Amount"));
perList.add(per);
}
}
//send the serialized object
String gabim="Ska asnje gabim";
String gabimNr="1";
t.sendResponseHeaders(200,0);
OutputStream os = t.getResponseBody();
SendResponse obj = new SendResponse(gabim,gabimNr,perList);
ObjectOutputStream objOut = new ObjectOutputStream(os);
objOut.writeObject(obj);
objOut.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
//ketu cojme nje object me keto te dhena
String gabim=("Dicka nuk shkoi mire me marrjen e objektit");
String gabimNr="3";
rrayList<Personat> perList = null;
t.sendResponseHeaders(200,0);
OutputStream os = t.getResponseBody();
SendResponse obj = new SendResponse(gabim,gabimNr,perList);
ObjectOutputStream objOut = new ObjectOutputStream(os);
objOut.writeObject(obj);
objOut.close();
} catch (SQLException e) {
//ketu cojme nje objekt me keto te dhena
e.printStackTrace();
String gabim=("Dicka nuk shkoi mire ne lidhje me databasin");
String gabimNr="4";
ArrayList<Personat> perList = null;
t.sendResponseHeaders(200,0);
OutputStream os = t.getResponseBody();
SendResponse obj = new SendResponse(gabim,gabimNr,perList);
ObjectOutputStream objOut = new ObjectOutputStream(os);
objOut.writeObject(obj);
objOut.close();
}
}
}
}
class Personat {
int ID;
String Name;
int Amount;
public int getID() {
return ID;
}
public void setID(int iD) {
ID = iD;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAmount() {
return Amount;
}
public void setAmount(int amount) {
Amount = amount;
}
}
class SendResponse implements Serializable {
private static final long serialVersionUID = 1L;
String gabim;
String gabimNr;
ArrayList<Personat> personList;
public SendResponse(String gabim, String gabimNr,
ArrayList<Personat> personList) {
super();
this.gabim = gabim;
this.gabimNr = gabimNr;
this.personList = personList;
}
public String getGabim() {
return gabim;
}
public void setGabim(String gabim) {
this.gabim = gabim;
}
public String getGabimNr() {
return gabimNr;
}
public void setGabimNr(String gabimNr) {
this.gabimNr = gabimNr;
}
public ArrayList<Personat> getPersonList() {
return personList;
}
public void setPersonList(ArrayList<Personat> personList) {
this.personList = personList;
}
}
after i run it from the ex.printStackTrace(); in the Client3 file i get this :
java.io.IOException: Premature EOF
java.io.IOException: Premature EOF
at sun.net.www.http.ChunkedInputStream.readAheadBlocking(Unknown Source)
at sun.net.www.http.ChunkedInputStream.readAhead(Unknown Source)
at sun.net.www.http.ChunkedInputStream.read(Unknown Source)
at java.io.FilterInputStream.read(Unknown Source)
at sun.net.www.protocol.http.HttpURLConnection$HttpInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.read(Unknown Source)
at java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(Unknown Source)
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at server3.Client3.main(Client3.java:29)
i dont know hot to read the file faster or make my program slower ,do someone have any idea ?

I don't think it's due to the speed of your program, I would expect readObject() to block if there wasn't anything to read. Instead I think you are missing a terminator in the data you are trying to read, you need to take a look at the data that is being sent to your program. A similar issue was resolved here, though it is using readLine()

Related

Minecraft plugin hanging on "Enabling plugin" and producing out of memory errors

Why would this code be having memory issues? It runs fine once, and then when I try to run it again it hangs on "Enabling plugin". It'll then give me an OutOfMemoryException such as
"Exception: java.lang.OutOfMemoryError thrown from the UncaughtExceptionHandler in thread "Worker-Main-10""
The code I am using is as follows from the Spigot API
import org.bukkit.Bukkit;
import org.bukkit.ChatColor;
import org.bukkit.entity.Bat;
import org.bukkit.entity.Entity;
import org.bukkit.entity.Player;
import org.bukkit.plugin.java.JavaPlugin;
import org.bukkit.scheduler.BukkitScheduler;
import java.io.*;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.UUID;
public class COVID19 extends JavaPlugin {
private static ArrayList<CovidInfection> infections;
#Override
public void onEnable() {
infections = new ArrayList<CovidInfection>();
System.out.println("1");
try {
readInfections();
} catch (FileNotFoundException fnfe) {
fnfe.printStackTrace();
}
System.out.println("2");
this.getCommand("getInfected").setExecutor(new CommandGetInfected());
BukkitScheduler scheduler = getServer().getScheduler();
scheduler.scheduleSyncRepeatingTask(this, new Runnable() {
#Override
public void run() {
batCovid();
}
}, 0, 10);
System.out.println(4);
}
#Override
public void onDisable() {
try {
writeInfections();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
public void batCovid() {
System.out.println(3);
for(Player player : Bukkit.getOnlinePlayers()) {
for(Entity nearby : player.getNearbyEntities(6, 6, 6)) {
if (nearby instanceof Bat) {
String name = player.getName();
UUID uuid = player.getUniqueId();
infections.add(new CovidInfection(uuid, name, 14));
}
}
}
}
public void readInfections() throws FileNotFoundException {
File file = new File("infected.txt");
if(file.length() == 0) {
return;
}
Scanner input = new Scanner(file);
String line = input.nextLine();
while (!(line.equals(""))) {
infections.add(parseInfectionLine(line));
}
input.close();
}
public void writeInfections() throws IOException {
//File will be written as UUID,Name,DaysRemaining
FileWriter writer = new FileWriter("infected.txt", false);
for(CovidInfection infection : infections) {
writer.write(infection.toString());
}
writer.close();
}
private CovidInfection parseInfectionLine(String line) {
String[] words = line.replace("\n","").split(",");
return new CovidInfection(UUID.fromString(words[0]), words[1], Integer.parseInt(words[2]));
}
public static String getInfected() {
String compiled = "";
for (CovidInfection infection : infections) {
compiled += infection.toString() + "\n";
}
return compiled;
}
}
import org.bukkit.ChatColor;
import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;
public class CommandGetInfected implements CommandExecutor {
#Override
public boolean onCommand(CommandSender sender, Command cmd, String label, String[] args) {
String message = COVID19.getInfected();
if(!(message.equals(""))) {
sender.sendMessage(message);
} else {
sender.sendMessage("There are no infected!");
}
return(true);
}
}
import java.util.UUID;
public class CovidInfection {
private UUID uuid;
private String name;
private int days;
public CovidInfection(UUID uuid, String name, int days) {
this.uuid = uuid;
this.name = name;
this.days = days;
}
public int getDays() {
return days;
}
public String getName() {
return name;
}
public UUID getUuid() {
return uuid;
}
public void newDay() {
days--;
}
public String toString() {
return uuid.toString() + "," + name + "," + days + "\n";
}
}
Any help would be greatly appreciated, thank you!
Firstly, you are make I/O request on main thread.
To fix this issue, use multithreading such as explained here or here
Then, this :
Scanner input = new Scanner(file);
String line = input.nextLine();
Can't be used in a server.
An input like that already exist, it's the console sender.
To do that, I suggest you to use ServerCommandEvent and use spigot's console.

java.io.EOFException when using sockets with blockchain in java

i have to do a practice in my uni, it must create a blockchain using sockets and serialization in a "simple way". But when exiting the loop (typing "NO") It creates a EOF exception that i cannot solve, while closing the socket(s.close()). i would appreciate some help, i am not vry good at java. here are my classes.
Client
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.Scanner;
public class Client implements Runnable{
public static void main(String[] args) throws Exception {
(new Thread(new Client())).start();
}
public static MedicalReport createReport(){
return new MedicalReport(10,"pepe","id","record");
}
#Override
public void run() {
// int port = 12345;
// String computer = "localhost";
try{
Socket s = new Socket("localhost", 12348);
ObjectOutputStream p = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
/* PrintWriter print = new PrintWriter(s.getOutputStream());
print.println("ready");
print.flush();*/
//manda informe al servidor serializado y espera respuesta
boolean stop = false;
while(!stop){
try{
MedicalReport report = createReport();
p.writeObject(report);
p.flush();
p.reset();
System.out.println("Do you want to continue? Yes or No");
Scanner in1 = new Scanner (System.in);
String answer="";
if(in1.hasNextLine())
answer = in1.nextLine();
if(!answer.equalsIgnoreCase("yes")){
System.out.println(report);
stop = true;
}
}
catch(Exception e){
System.out.println(e);
}
}
try{
s.close();
}
catch(Exception e){
System.out.println(e);
}
}catch(Exception e){
System.out.println(e);
}
}
}
SERVER
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Scanner;
public class Server {
public static void main(String[] args)
throws Exception
{
ArrayList<Block> blockChain = new ArrayList<>();
try{
ServerSocket ss = new ServerSocket(12348);
Socket s = ss.accept();
ObjectOutputStream out = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream in = new ObjectInputStream(s.getInputStream());
/* Scanner scanner = new Scanner(s.getInputStream());
String text = scanner.nextLine();*/
int i = 0;
int previousHash = 0;
while (i != 20){
MedicalReport rp = (MedicalReport)in.readObject();
Block block = new Block(rp,previousHash);
blockChain.add(block);
System.out.println("Block " + blockChain.size() + " added to blockchain");
System.out.println(blockChain.get(i));
previousHash = block.getBlockHash();
System.out.println(blockChain);
i++;
}
try{
ss.close();
}
catch(Exception e){
System.out.println(e);
}
}catch(Exception e){
System.out.println(e);
}
}
}
It looks like the error is while closing the socket, any idea?
EDIT REST OF THE CODE
MEDICAL REPORT
import java.io.Serializable;
public class MedicalReport implements Serializable {
private int age;
private String name;
private String id;
private String record;
private static final long serialVersionUID = 1L;
public MedicalReport(){super();}
public MedicalReport(int age, String name, String id, String record) {
super();
this.age = age;
this.name = name;
this.id = id;
this.record = record;
}
public String getRecord(){
return this.record;
}
public String toString(){
return this.name + ". \n" + this.age + ". \n" + this.id + ". \n" + this.record;
}
}
BLOCK
public class Block {
private int blockHash;
private int previousHash;
private MedicalReport report;
//Block Constructor.
public Block(MedicalReport report,int previousHash ) {
this.previousHash = previousHash;
this.report = report;
this.blockHash = report.hashCode();
}
public int getPreviousHash() {
return previousHash;
}
public MedicalReport getReport() {
return report;
}
public int getBlockHash() {
return blockHash;
}
}
EDIT 2
FIRST QUESTION SOLVED. Now i get this error when exiting the loop:
java.net.SocketException: Connection reset by peer: socket write error
readObject() throws EOFEzception when the peer has closed the connection. This is normal. Catch it and stop reading. There is no problem here to solve.
IMPORTANT: As EJP said EOFException is normal and you can control the flow of your code with it but if you still want to know how to do in the way you asked here it is. REMEMBER THIS IS JUST FULFILL YOUR QUESTION AND NOT ADVISED TO DO SO.
On Server Class
Replace
MedicalReport rp = (MedicalReport)in.readObject();
With
MedicalReport rp;
if((rp = (MedicalReport)in.readObject())==null) break;
On Client Class
ADD
p.writeObject(null);
Just above the s.close(); statement
You must know that when a peer close the connection normally then
read() returns -1,
readLine() returns null,
readXXX() throws EOFException for any other XXX
And A write will throw an IOException

How to create a java Server that accepts client connections and then build a relay connection for a client pair

I want to create a server that can accept multiple connections and then bind 2 clients as a pair and forward the data between these 2 clients. But it is about multiple pairs of clients. I already have multithread server that can create a new thread for each new connected client. The problem for me is that these threads dont know of each other and somehow I have to connect 2 clients to a connection pair.
For now I just create these pair connection as this: I wait for the first client, then I wait for the second client and then open a thread for the input of client 1 that gets forwarded to client 2 and the other way around. This is not usable for multiple clients.
How can I do this decent?
The way I see it, a client would need to
establish a TCP(?) connection with your server,
identify itself
give the ID of the other client it wishes to talk to
The first that connects would have to be kept on hold (in some global table in your server) until the second client connects.
Once a pair of clients would have been recognized as interlocutors, you would create a pair of threads to forward the data sent by each client to the other one.
UPDATE: Example
ClientSocket.java
package matchmaker;
import java.io.Closeable;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class ClientSocket implements Closeable {
private final Socket socket;
private final InputStream in;
private final OutputStream out;
private final String ownId;
private final String peerId;
public ClientSocket(Socket socket) throws IOException {
this.socket = socket;
this.in = socket.getInputStream();
this.out = socket.getOutputStream();
DataInputStream din = new DataInputStream(in);
this.ownId = din.readUTF();
this.peerId = din.readUTF();
}
public ClientSocket(String server, int port, String ownId, String peerId)
throws IOException {
this.socket = new Socket(server, port);
this.socket.setTcpNoDelay(true);
this.in = socket.getInputStream();
this.out = socket.getOutputStream();
this.ownId = ownId;
this.peerId = peerId;
DataOutputStream dout = new DataOutputStream(out);
dout.writeUTF(ownId);
dout.writeUTF(peerId);
}
public String getOwnId() {
return ownId;
}
public String getPeerId() {
return peerId;
}
public InputStream getInputStream() {
return in;
}
public OutputStream getOutputStream() {
return out;
}
#Override
public void close() throws IOException {
socket.close();
}
}
Matchmaker.java: the server
package matchmaker;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.util.HashMap;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
public class Matchmaker extends Thread {
private static final Logger LOG
= Logger.getLogger(Matchmaker.class.getName());
private final int port;
private final Map<ClientPair,ClientSocket> waiting = new HashMap<>();
public static void main(String[] args) {
try {
int port = 1234;
int st = 0;
for (String arg: args) {
switch (st) {
case 0:
switch (arg) {
case "-p":
st = 1;
break;
default:
System.out.println("Unknown option: " + arg);
return;
}
break;
case 1:
port = Integer.parseInt(arg);
st = 0;
break;
}
}
Matchmaker server = new Matchmaker(port);
server.start();
server.join();
} catch (InterruptedException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
private Matchmaker(int port) {
this.port = port;
setDaemon(true);
}
#Override
public void run() {
try {
ServerSocket server = new ServerSocket(port);
while (true) {
ClientSocket socket = new ClientSocket(server.accept());
ClientPair pair = new ClientPair(
socket.getOwnId(), socket.getPeerId());
ClientSocket other;
synchronized(this) {
other = waiting.remove(pair.opposite());
if (other == null) {
waiting.put(pair, socket);
}
}
if (other != null) {
LOG.log(Level.INFO, "Establishing connection for {0}",
pair);
establishConnection(socket, other);
} else {
LOG.log(Level.INFO, "Waiting for counterpart {0}", pair);
}
}
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
private void establishConnection(ClientSocket socket, ClientSocket other)
throws IOException {
Thread thread = new StreamCopier(
socket.getInputStream(), other.getOutputStream());
thread.start();
thread = new StreamCopier(
other.getInputStream(), socket.getOutputStream());
thread.start();
}
}
StreamCopier.java: a thread that reads from an InputStream and writes to an OutputStream
package matchmaker;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
public class StreamCopier extends Thread {
private static final Logger LOG
= Logger.getLogger(StreamCopier.class.getName());
private final InputStream in;
private final OutputStream out;
public StreamCopier(InputStream in, OutputStream out) {
this.in = in;
this.out = out;
setDaemon(true);
}
#Override
public void run() {
LOG.info("Start stream copier");
try {
for (int b = in.read(); b != -1; b = in.read()) {
out.write(b);
}
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
} finally {
LOG.info("End stream copier");
try {
out.close();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
}
}
ClientPair.java: a pair of client IDs
package matchmaker;
public class ClientPair {
private final String client1;
private final String client2;
public ClientPair(String client1, String client2) {
this.client1 = client1;
this.client2 = client2;
}
public String getClient1() {
return client1;
}
public String getClient2() {
return client2;
}
public ClientPair opposite() {
return new ClientPair(client2, client1);
}
#Override
public int hashCode() {
int hash = 5;
hash = 73 * hash + client1.hashCode();
hash = 73 * hash + client2.hashCode();
return hash;
}
#Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ClientPair other = (ClientPair) obj;
return client1.equals(other.client1) && client2.equals(other.client2);
}
#Override
public String toString() {
return "[" + client1 + "," + client2 + "]";
}
}
ReaderClient.java: a sample client that reads from the socket and writes to standard output
package matchmaker;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.logging.Level;
import java.util.logging.Logger;
public class ReaderClient {
private static final Logger LOG = Logger.getLogger(ReaderClient.class.getName());
public static void main(String[] args) {
try (ClientSocket client
= new ClientSocket("localhost", 1234, "reader", "writer")) {
Reader reader
= new InputStreamReader(client.getInputStream(), "UTF-8");
BufferedReader in = new BufferedReader(reader);
for (String s = in.readLine(); s != null; s = in.readLine()) {
System.out.println(s);
}
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
}
WriterClient.java: a sample client that writes to the socket
package matchmaker;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.logging.Level;
import java.util.logging.Logger;
public class WriterClient {
private static final Logger LOG = Logger.getLogger(ReaderClient.class.getName());
public static void main(String[] args) {
try (ClientSocket client
= new ClientSocket("localhost", 1234, "writer", "reader")) {
Writer writer
= new OutputStreamWriter(client.getOutputStream(), "UTF-8");
PrintWriter out = new PrintWriter(writer);
for (int i = 0; i < 30; ++i) {
out.println("Message line " + i);
}
out.flush();
} catch (IOException ex) {
LOG.log(Level.SEVERE, null, ex);
}
}
}

How to Organize Commands/Handlers on Socket Game Server?

I am working on a socket server for a MMORPG I am creating, and I am unsure how to organize commands and handlers for readability.
I will be getting the command from data[0], such as ban, kick, identify, etc. I have read that you can use a HashMap and have an Interface Command, and create a new class for each handler/command that implements Command. You'd then create a HashMap and go from there. I have also read that you can reflection. I want to do what an experienced programmer would do.
Client Class:
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 Socket socket;
private Server server;
private boolean isConnected;
private BufferedReader in;
private PrintWriter out;
public Client(Socket socket, Server server) {
this.socket = socket;
this.server = server;
this.isConnected = true;
this.in = null;
this.out = null;
}
#Override
public void run() {
try {
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
out = new PrintWriter(socket.getOutputStream(), true);
while (isConnected) {
String recv = in.readLine().trim();
if (recv != null) {
String[] data = recv.split("%");
}
}
} catch (IOException e) {}
}
public synchronized void send(String data) {
out.println(data);
}
}
What you want is to use the Command Pattern.
Here is how I would use the Command Pattern for handling commands from a client.
/* Command Exception. */
public class ClientCommandException extends Exception {
public ClientCommandException(String msg) {
super(msg);
}
}
/* The ClientCommand interface */
public interface ClientCommand {
void execute(Client client, String[] params) throws ClientCommandException;
}
import java.util.HashMap;
import java.util.Arrays;
/* Container for commands */
public class Commands implements ClientCommand {
private HashMap<String, ClientCommand> cmds;
public Commands() {
cmds = new HashMap<String, ClientCommand>();
}
public void addCommand(ClientCommand cmd, String name) {
cmds.put(name, cmd);
}
public void execute(Client client, String[] params) throws ClientCommandException {
ClientCommand cmd = cmds.get(params[0]);
if(cmd != null) {
cmd.execute(client, Arrays.copyOfRange(params, 1, params.length));
} else {
throw new ClientCommandException("Unknown Command: " + params[0]);
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
public class Client implements Runnable {
private boolean isConnected;
private Commands cmds;
private BufferedReader in;
private PrintWriter out;
private class EchoCommand implements ClientCommand {
public void execute(Client client, String[] params) throws ClientCommandException {
StringBuilder b = new StringBuilder("Echo back:");
int len = params.length;
for(int i = 0; i < len; i++) {
b.append(' ');
b.append(params[i]);
}
client.send(b.toString());
}
}
private class DisconnectCommand implements ClientCommand {
public void execute(Client client, String[] params) throws ClientCommandException {
client.close();
}
}
public Client() {
cmds = new Commands();
cmds.addCommand(new EchoCommand(), "echo");
cmds.addCommand(new DisconnectCommand(), "disconnect");
/* sub-commands */
Commands server = new Commands();
server.addCommand(new EchoCommand(), "print");
cmds.addCommand(server, "server");
isConnected = true;
}
public void addCommand(ClientCommand cmd, String name) {
cmds.addCommand(cmd, name);
}
public void close() {
isConnected = false;
}
#Override
public void run() {
try {
in = new BufferedReader(new InputStreamReader(System.in));
out = new PrintWriter(System.out, true);
while (isConnected) {
String recv = in.readLine().trim();
if (recv != null) {
String[] data = recv.split("%");
try {
cmds.execute(this, data);
} catch(ClientCommandException e) {
/* Return some error back to the client. */
out.println(e.toString());
}
}
}
} catch (IOException e) {}
}
public synchronized void send(String data) {
out.println(data);
}
public static void main(String[] args){
Client client = new Client();
System.out.println("Start Client.");
client.run();
}
}

Java network object serialization

Im trying to send an object from client to server and one of the object states is a vector and the other is a string. I can access the string on the Server side, but the vector contents is zero on the server side..Can someone help me out please..
// Server
import java.net.*;
import java.util.Vector;
import java.io.*;
public class SimpleServer {
public static void main(String args[]) {
int port = 2002;
try {
System.out.println("Hello");
ServerSocket ss = new ServerSocket(port);
Socket s = ss.accept();
System.out.println("Hello 2");
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to = (testobject)ois.readObject();
System.out.println("Vector size : " + to.vectorX.size() + " and object.id : "
+ to.id);
/* if (to != null) {
for(int i = 0; i < to.vectorX.size(); ++i )
System.out.println("Output 1 : " + to.vectorX.elementAt(i));
} */
is.close();
s.close();
ss.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
// Client
import java.net.*;
import java.io.* ;
import java.util.Vector;
public class SimpleClient {
protected static Vector<String> vectorX = new Vector<String>();
public SimpleClient(){
vectorX.addElement("hello");
vectorX.add("goodbye");
vectorX.add("finally");
}
public static void main(String args[]) {
try {
new SimpleClient();
Socket s = new Socket("localhost", 2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
testobject to = new testobject(1, "theID", vectorX );
System.out.println(vectorX.size());
oos.writeObject(to);
// oos.writeObject(new String("another object from the client"));
oos.close();
os.close();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
//testobject
import java.net.*;
import java.io. * ;
import java.util.Vector;
class testobject implements Serializable {
int value;
String id;
Vector<String> vectorX;
public testobject(int v, String s, Vector<String> vector) {
this.value = v;
this.id = s;
this.vectorX = new Vector<String>();
}
}
The constructor for your testobject is not using the vector argument. It is rather assigning the vectorX ivar to a new instance, ignoring the parameter provided by the caller:
public testobject(int v, String s, Vector<String> vector) {
this.value = v;
this.id = s;
this.vectorX = new Vector<String>(); // This is bad
}
You should instead use:
public testobject(int v, String s, Vector<String> vector) {
this.value = v;
this.id = s;
this.vectorX = vector;
}
Note: It's not common for class names in Java to be all lowercase, or to start with a lowercase letter. As an aside, I think you should rename your class to TestObject.

Categories

Resources