I am creating a remote-desktop screenshot application. I have two methods on the server 1) To read the Image from client 2) to read the list of task running on the client). But everytime I try to read the client's input stream an EOF excetion is thrown. The stakctrace of the exception is
java.io.EOFException at
java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2323)
at
java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:2792)
at
java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:799)
at java.io.ObjectInputStream.(ObjectInputStream.java:299) at
remoteserverclient.original.ScreenServer$ServerThread.run(ScreenServer.java:254)
Here is the code on the server where the exception is thrown
ObjectInputStream in = new ObjectInputStream(client.getInputStream());
Object obj = in.readObject();
if (obj instanceof Rectangle) {
CaptureScreen(obj, in);
} else if (obj instanceof String) {
CaptureList(in);
}
Here is the complete code for the client
public class ScreenClient {
static Socket server;
public static void main(String[] args) throws Exception {
try {
while (true) {
server = new Socket("localhost", 5494);
BufferedReader bf = new BufferedReader(new InputStreamReader(server.getInputStream()));
String s;
s = bf.readLine();
System.out.println(s);
if (s.contains("execute")) {
new ClientMessageThread().start();
}
if (s.contains("getProcessList")) {
new ClientFetchProcessThread().start();
}
}
} catch (Exception e) {
System.err.println("Disconnected From server ->" + e.getMessage());
}
}
public static class ClientMessageThread extends Thread {
Socket server;
public ClientMessageThread() {
try {
server=new Socket("localhost",5494);
} catch (Exception ex) {
ex.printStackTrace();
}
}
#Override
public void run() {
try {
BufferedImage screen;
Robot robot = new Robot();
Rectangle size = new Rectangle(Toolkit.getDefaultToolkit().getScreenSize());
screen = robot.createScreenCapture(size);
int[] rgbData = new int[(int) (size.getWidth() * size.getHeight())];
screen.getRGB(0, 0, (int) size.getWidth(), (int) size.getHeight(), rgbData, 0, (int) size.getWidth());
OutputStream baseOut = server.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(baseOut);
out.writeObject(size);
for (int x = 0; x < rgbData.length; x++) {
out.writeInt(rgbData[x]);
}
out.flush();
server.close();
//added new
} catch (Exception e) {
System.err.println("Disconnected From server ->" + e.getMessage());
}
}
}
public static class ClientFetchProcessThread extends Thread {
Socket server;
public ClientFetchProcessThread() {
try {
server=new Socket("localhost",5494);
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void run() {
try {
PrintWriter ps;
System.out.println("\n\n********");
StringBuilder builder = new StringBuilder("");
String query = "tasklist";
Runtime runtime = Runtime.getRuntime();
InputStream input = runtime.exec(query).getInputStream();
BufferedInputStream buffer = new BufferedInputStream(input);
BufferedReader commandResult = new BufferedReader(new InputStreamReader(buffer));
String line = "";
ps = new PrintWriter(server.getOutputStream(), true);
while ((line = commandResult.readLine()) != null) {
builder.append(line + "\n");
//byte[] responseClient=s.getBytes();
ps.write(builder.toString());
System.out.println(builder.toString());
}
server.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
You're both printing and writing objects to port 5494 from the client. The server only reads objects.
Sort it out.
The exception being thrown is EOFException (End of file exception).
ObjectInputStream throws EOFException when it reaches the end of the input. That's standard behaviour. Are you catching all exceptions thrown by in.readObject()?
Documentation:
http://docs.oracle.com/javase/7/docs/api/java/io/ObjectInputStream.html
Related
I'm trying to create a proxy application, but I'm facing problems in server socket. The Server Socket is not accepting the connection and returning a socket. Hence, I cannot test the proxy application. What is wrong?
The problem line is indicated in WebServe.java:
public class WebServe implements Runnable {
Socket soc;
OutputStream os;
BufferedReader is;
String resource;
WebServe(Socket s) throws IOException {
soc = s;
os = soc.getOutputStream();
is = new BufferedReader(new InputStreamReader(soc.getInputStream()));
}
public void run() {
System.err.println("Running");
getRequest();
returnResponse();
close();
}
public static void main(String args[]) {
try {
System.out.println("Proxy Thread");
ServerSocket s = new ServerSocket(8080);
for (;;) {
s.setSoTimeout(10000);
WebServe w = new WebServe(s.accept()); // Problem is here
Thread thr = new Thread(w);
thr.start();
w.getRequest();
w.returnResponse();
w.close();
}
} catch (IOException i) {
System.err.println("IOException in Server");
}
}
void getRequest() {
System.out.println("Getting Request");
try {
String message;
while ((message = is.readLine()) != null) {
if (message.equals("")) {
break;
}
System.err.println(message);
StringTokenizer t = new StringTokenizer(message);
String token = t.nextToken();
if (token.equals("GET")) {
resource = t.nextToken();
}
}
} catch (IOException e) {
System.err.println("Error receiving Web request");
}
}
void returnResponse() {
int c;
try {
FileInputStream f = new FileInputStream("." + resource);
while ((c = f.read()) != -1) {
os.write(c);
}
f.close();
} catch (IOException e) {
System.err.println("IOException is reading in web");
}
}
public void close() {
try {
is.close();
os.close();
soc.close();
} catch (IOException e) {
System.err.println("IOException in closing connection");
}
}
}
public static void main(String args[]){
try {
System.out.println("Proxy Thread");
ServerSocket s = new ServerSocket (8080);
for (;;){
s.setSoTimeout(10000);
Move that ahead of the loop. You don't need to keep setting it. You don't really need it at all actually.
WebServe w = new WebServe (s.accept()); //Problem is here
The problem is here only because you set a socket timeout you don't actually need.
Thread thr = new Thread (w);
thr.start();
So far so good.
w.getRequest();
w.returnResponse();
w.close();
Remove. The next problem is here. The run() method of WebServ already does this.
As to the rest, you aren't writing an HTTP header in the response.
I am making a simple ftp client/server program which on command from the clients lists files, tells the current directory, downloads files
My client code works fine since i have already tested it with a working server. However the server that i have designed gets stuck in the run() function on the line String message = br.readline(); If instead i use the br.read(), then it works but i need command in form of a string to know which file i have to download whereas br.read() returns int. Here's my code, i have used threading.
public class Myserver {
static final int PortNumber = 108;
static ServerSocket MyService;
static Socket clientSocket = null;
/**
* #param args
* #throws IOException
*/
public static void main(String[] args) throws IOException {
File directory;
directory = new File(System.getProperty("user.home"));
try {
MyService = new ServerSocket(PortNumber);
String cd = directory.toString();
System.out.println(cd);
System.out.println("Listening on " + PortNumber);
while(true) {
clientSocket = MyService.accept();
Connecthandle a = new Connecthandle(clientSocket, directory);
a.run();
}
}
catch (IOException e) {
System.out.println(e);
}
}
static class Connecthandle extends Thread {
File Directory;
Socket clientsocket;
// Constructor for class
Connecthandle(Socket clients, File dir) {
clientsocket = clients;
Directory = dir;
}
// Works Fine
void listfiles() throws IOException {
String []Listfile = Directory.list();
String send = "";
for (int j = 0; j < Listfile.length; j++) {
send = send + Listfile[j] + ",";
}
DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
GoingOut.writeBytes(send);
GoingOut.flush();
GoingOut.close();
}
// Works Fine
void currentdirectory() throws IOException {
String cd = Directory.toString();
String cdd = "resp," + cd;
System.out.println(cdd);
DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
GoingOut.writeBytes(cdd);
GoingOut.flush();
GoingOut.close();
System.exit(0);
}
void sendfiles(String fileName) {
try {
File nfile = new File(fileName);
DataOutputStream GoingOut = new DataOutputStream(clientsocket.getOutputStream());
if ( (! nfile.exists()) || nfile.isDirectory() ) {
GoingOut.writeBytes("file not present");
} else {
BufferedReader br = new BufferedReader(new FileReader(nfile));
String line;
while ((line = br.readLine()) != null) {
line = br.readLine();
GoingOut.writeBytes(line+"\n");
}
GoingOut.flush();
GoingOut.close();
br.close();
}
} catch (IOException e) {
System.out.println("Unable to send!");
}
}
#SuppressWarnings("deprecation")
public void run() {
try {
DataInputStream comingin = new DataInputStream(clientsocket.getInputStream());
InputStreamReader isr = new InputStreamReader(comingin, "UTF-8");
BufferedReader br = new BufferedReader(isr);
System.out.println("here");
// if (br.ready())
String message = br.readLine(); // Code gets stuck here, if i use br.read() it works, but i need string output.
if (message.equals("listfiles\n")) {
listfiles();
} else if (message.equals("pwd")) {
currentdirectory();
} else if (message.contains("getfile,")) {
String fileName = new String(message.substring(8, message.length()));
sendfiles(fileName);
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
clientsocket.close();
} catch (IOException e) {}
}
}
}
}
If readLine() is blocking and you are sending data, you aren't sending a newline.
hello I am using this method to read a message:
public String readMessage() {
int read = -1;
byte[] buffer = new byte[5*1024];
byte[] redData;
try {
while ((read = this.session.getInputStream().read(buffer)) > -1) {
redData = new byte[read];
System.arraycopy(buffer, 0, redData, 0, read);
return new String(redData,"UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
And when I write something like "hello how are you today?"
Response (Exact format, including these new lines):
[/127.0.0.1:54930]:
[/127.0.0.1:54930]: are
[/127.0.0.1:54930]: you
[/127.0.0.1:54930]: today?
Thats how I read chat messages, first I check which packet was requested, if the packet type was 0, then I get instance of packethandler, and pass the client object to the Chat handling packet which will read the message here, like this:
public void startClientService() throws IOException {
while(true) {
int packetType = this.in.read();
packets.getPacket(packetType);
}
}
public void getPacket(int packetType) {
switch (packetType) {
case 0:
chat.processPacket(this.client);
break;
}
}
And the chat packet:
#Override
public void processPacket(Session c) {
String clientMessage = c.readMessage();
System.out.println("[" + c.getStream().getRemoteSocketAddress() + "]: " + clientMessage.toString());
}
And there the print message happens.
Why does it print parts of the messages, in new lines? not even the full message.
This is my client:
public static void main(String[] args) throws UnknownHostException, IOException {
Socket socket = new Socket("127.0.0.1", 43594);
Scanner r = new Scanner(System.in);
PrintWriter out = new PrintWriter(socket.getOutputStream());
String input;
while(true) {
input = r.next();
if (input != null) {
sendMessage(input, out);
}
}
}
public static void sendMessage(String message, PrintWriter out) {
out.write(0);
out.flush();
out.write(message + "\n");
out.flush();
}
Thanks.
Session:
public class Session extends Thread implements Runnable {
private Socket session;
private Client client;
private PrintWriter out;
private BufferedReader in;
private PacketHandler packets;
public Session(Socket session) {
this.session = session;
this.client = new Client(this);
try {
this.setStream();
} catch (IOException e) {
e.printStackTrace();
}
this.packets = new PacketHandler(this);
System.out.println("[New session created]: " + session.getRemoteSocketAddress());
}
public void run() {
try {
this.startClientService();
} catch (IOException e) {
e.printStackTrace();
}
}
public Socket getStream() {
return this.session;
}
public void setStream() throws IOException {
this.out = new PrintWriter(this.session.getOutputStream());
this.in = new BufferedReader(new InputStreamReader(this.session.getInputStream()));
}
public Client getClient() {
return this.client;
}
public String readMessage() {
int read = -1;
byte[] buffer = new byte[5*1024];
byte[] redData;
try {
while ((read = this.session.getInputStream().read(buffer)) > -1) {
redData = new byte[read];
System.arraycopy(buffer, 0, redData, 0, read);
return new String(redData,"UTF-8");
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
public void startClientService() throws IOException {
while(true) {
int packetType = this.in.read();
packets.getPacket(packetType);
}
}
public void destruct() throws IOException {
this.session.close();
System.out.println("Session killed");
}
}
looks like you are returning as soon as you get some data from stream.
while ((read = this.session.getInputStream().read(buffer)) > -1) {
redData = new byte[read];
System.arraycopy(buffer, 0, redData, 0, read);
return new String(redData,"UTF-8");
}
Read the data completely and make a string object out of it and return it
BufferedReader br = new BufferedReader(new InputStreamReader(this.session.getInputStream()));
String msg = br.readLine();
br.close();
return msg;
try this way. This will give you entire data to a buffer and can return as line of string.No need of loop
The the amount of data returned from one call to read has no relationship to how the
data divided when sent. One send can result in any number of reads, and multiple sends
may be combined into one read.
What I want are just the responses from wunderground printed to the console:
public class Weather {
public static void main(String[] args) {
String host = "rainmaker.wunderground.com";
int port = 3000;
int c;
{
try (Socket socket = new Socket(host, port);
PrintWriter printWriter = new PrintWriter(socket.getOutputStream(), true);
final BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in))) {
while (true) {
System.out.println(socket.toString());
c = bufferedReader.read();
System.out.print((char) c);
}
} catch (IOException ex) {
System.out.println(ex + host + port);
System.exit(1);
} finally {
System.exit(1);
}
}
}
}
However, there's not much output to go on:
thufir#dur:~/NetBeansProjects/MudSocketClient$
thufir#dur:~/NetBeansProjects/MudSocketClient$ java -jar dist/MudSocketClient.jar
Socket[addr=rainmaker.wunderground.com/38.102.137.140,port=3000,localport=53550]
^Cthufir#dur:~/NetBeansProjects/MudSocketClient$
thufir#dur:~/NetBeansProjects/MudSocketClient$
Running telnet from the CLI, the connection works fine.
I found some old code:
public class InputOutput extends Observable {
private static final Logger log = Logger.getLogger(InputOutput.class.getName());
private Alias alias = new Alias();
public InputOutput() {
}
private void readFromConsole(final OutputStream outputStream) {
Thread read = new Thread() {
#Override
public void run() {
String line;
byte[] bytes;
Scanner scanner;
while (true) {
GameDataBean gameData = null;
scanner = new Scanner(System.in);
line = scanner.nextLine();
try {
gameData = alias.parseUserInput(line);
} catch (StringIndexOutOfBoundsException e) {
log.fine(e.toString());
}
if (gameData != null) {
setChanged();
notifyObservers(gameData);
} else {
bytes = line.getBytes();
try {
outputStream.write(bytes);
outputStream.write(10);
outputStream.flush();
} catch (IOException ex) {
log.fine(ex.toString());
}
}
}
}
};
read.start();
}
private void readInput(final InputStream inputStream) throws FileNotFoundException, IOException {
Thread readInput = new Thread() {
#Override
public void run() {
char ch = 0;
int intVal = 0;
StringBuilder sb = new StringBuilder();
try {
while ((intVal = inputStream.read()) != -1) {
ch = (char) intVal;
printToConsole(ch);
//logToFile(ch);
sb.append(ch);
if (intVal == 13) {
setChanged();
notifyObservers(sb.toString());
sb = new StringBuilder();
}
}
} catch (IOException ex) {
Logger.getLogger(InputOutput.class.getName()).log(Level.SEVERE, null, ex);
}
}
private void logToFile(char c) throws IOException {
String fname = "weather.log";
File f = new File(fname);
f.createNewFile();
try (PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(fname, true)))) {
out.print(c);
out.flush();
}
}
private void printToConsole(char c) {
System.out.print(c);
}
};
readInput.start();
}
public void readWriteParse(final InputStream inputStream, final OutputStream outputStream) throws FileNotFoundException, IOException {
readFromConsole(outputStream);
readInput(inputStream);
}
}
I think it's that, when the socket is still open, it has to be multi-threaded, as I recall.
In this code I can correctly receive a request using BufferedReader inClient, created on the client socket.
Then I send the request to the server and I see the server gets it.
But then, when I try to read the reply from the server (using BufferedReader inServer on the socket of the server), it always ends in IOException: Impossible read from server.
I am referring to the block ################
Do you know any possible reasons?
import java.io.*;
import java.net.Socket;
import java.net.ServerSocket;
import java.net.InetAddress;
import java.net.UnknownHostException;
public class ProxyMain {
public static void main(String argv[]) {
int proxyPort = 55554;
String proxyAddr = "127.0.0.1";
ServerSocket proxySocket = null;
try {
proxySocket = new ServerSocket(proxyPort, 50, InetAddress.getByName("127.0.0.1"));
}
catch (Exception e) {
System.err.println("Impossible to create socket server!");
System.out.flush();
System.exit(1);
}
System.out.printf("Proxy active on port: %d and on address %s\n", proxyPort, proxySocket.getInetAddress());
System.out.println();
while (true) {
Socket client = null;
Socket sockServ = null;
BufferedReader inClient = null;
PrintWriter outClient = null;
BufferedReader inServer = null;
PrintWriter outServer = null;
String request = new String();
String tmp = new String();
String reply = new String();
String tmpReply = new String();
try {
client = proxySocket.accept();
System.out.println("Connected to: ");
System.out.println(client.getInetAddress().toString());
System.out.printf("On port %d\n", client.getPort());
System.out.println();
inClient = new BufferedReader(new InputStreamReader(client.getInputStream()));
outClient = new PrintWriter(client.getOutputStream(), true);
}
/*catch (IOException e) {
System.err.println("Couldn't get I/O for connection accepted");
System.exit(1);
}*/
catch (Exception e) {
System.out.println("Error occurred!");
System.exit(1);
}
System.out.println("Received request:");
try{
for (int i = 0; i<2; i++) {
tmp = inClient.readLine();
request = request + tmp;
}
inClient.close();
}
catch (IOException ioe) {
System.err.println("Impossible to read mhttp request!");
System.exit(1);
}
System.out.println(request);
System.out.println();
try {
sockServ = new Socket("127.0.0.1", 55555);
outServer = new PrintWriter(sockServ.getOutputStream(), true);
inServer = new BufferedReader(new InputStreamReader(sockServ.getInputStream()));
}
catch (UnknownHostException e) {
System.err.println("Don't know about host: 127.0.0.1:55555");
System.exit(1);
}
catch (IOException e) {
System.err.println("Couldn't get I/O for the connection to: 127.0.0.1:55555");
System.exit(1);
}
outServer.println(request);
outServer.close();
try {
#################################################
while ((tmpReply = inServer.readLine()) != null) {
System.out.println(tmpReply);
reply = reply + tmpReply;
}
inServer.close();
sockServ.close();
}
catch (IOException ioe) {
System.err.println("Impossible to read from server!");
System.exit(1);
}
outClient.println(reply);
outClient.close();
try {
client.close();
}
catch (IOException ioe) {
System.err.printf("Impossible to close connection with %s:%d\n", client.getInetAddress().toString(), client.getPort());
}
}
}
}
UPDATE:
It seems that if I do:
boolean res = inServer.ready();
it always return false.
So Server is not ready to send the reply but this is strange...with my Project in C e Python it worked immediately. Why should java be different?
When you close outServer, you close the underlying socket. if you just want to close the output and keep the input open, you need to use Socket.shutdownOutput(). note, you have the same problem when you close inClient.
This works, maybe you can get some ideas from it...
ChatServer - broadcasts to all connected clients
In one command prompt: java ChartServer
In another: java ChatClient localhost (or the ip address of where the server is running)
And another: java ChatClient localhost (or the ip address of where the server is running)
Start chatting in the client windows.
Server like this...
// xagyg wrote this, but you can copy it
import java.io.*;
import java.net.*;
import java.util.*;
public class ChatServer {
public static List list = new ArrayList();
public static void main(String[] args) throws Exception {
ServerSocket svr = new ServerSocket(4444);
System.out.println("Chat Server started!");
while (true) {
try {
Socket s = svr.accept();
synchronized(list) {
list.add(s);
}
new Handler(s, list).start();
}
catch (IOException e) {
// print out the error, but continue!
System.err.println(e);
}
}
}
}
class Handler extends Thread {
private Socket s;
private String ipaddress;
private List list;
Handler (Socket s, List list) throws Exception {
this.s = s;
ipaddress = s.getInetAddress().toString();
this.list = list;
}
public void run () {
try {
BufferedReader reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
String message;
//MyDialog x = (MyDialog)map.get(ipaddress.substring(1));
while ((message = reader.readLine()) != null) {
if (message.equals("quit")) {
synchronized(list) {
list.remove(s);
}
break;
}
synchronized(list) {
for (Object object: list) {
Socket socket = (Socket)object;
if (socket==s) continue;
PrintWriter writer = new PrintWriter(socket.getOutputStream());
writer.println(ipaddress + ": " + message);
writer.flush();
}
}
}
try { reader.close(); } catch (Exception e) {}
}
catch (Exception e) {
System.err.println(e);
}
}
}
Client like this ...
// xagyg wrote this, but you can copy it
import java.util.*;
import java.io.*;
import java.net.*;
public class ChatClient {
public static void main(String[] args) throws Exception {
Socket s = new Socket(args[0], 4444);
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
PrintWriter out = new PrintWriter(s.getOutputStream());
BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
String message;
new SocketReader(in).start();
while ((message = reader.readLine())!=null) {
out.println(message);
out.flush();
if (message.equals("quit")) break;
}
in.close();
out.close();
}
}
class SocketReader extends Thread {
BufferedReader in;
public SocketReader(BufferedReader in) {
this.in = in;
}
public void run() {
String message;
try {
while ((message = in.readLine())!=null) {
System.out.println(message);
}
}
catch (Exception e) {
throw new RuntimeException(e);
}
}
}