I'm trying to send a blank TCP packet to a server running on port 80 however it gives me an EOFException when the server responds.
java.io.EOFException
at java.io.ObjectInputStream$PeekInputStream.readFully(ObjectInputStream.java:2624)
at java.io.ObjectInputStream$BlockDataInputStream.readShort(ObjectInputStream.java:3099)
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:853)
at java.io.ObjectInputStream.(ObjectInputStream.java:349)
at me.adamstephenson.test.main.main(main.java:106)
ArrayList<String> results = getIPs();
for (String ip : results){
System.out.println(ip);
String pingip = ip;
pingip = pingip.replaceAll("[^\\d.]", "");
System.out.println(pingip);
Socket socket = null;
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
try {
socket = new Socket(pingip, 80);
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream()); // error here
String msg = "blank";
oos.write(msg.getBytes());
oos.flush();
//read the server response message
String message = (String) ois.readObject();
System.out.println(message);
ois.close();
oos.close();
socket.close();
} catch (ConnectException | EOFException e) {
System.out.println("Failed to connect to: "+pingip);
e.printStackTrace();
}
}
Does the EOFException mean that the response was blank?
It means that the server didn't even create an ObjectOutputStream before closng the socket. Probably you sent it something it didn't understand, and maybe the application protocol it uses doesn't involve Serialization at all.
Port 80 is reserved for HTTP after all.
Related
So, I just learned how to make sockets and all that good stuff in Java, and so my first try got me a message from the client, and then the client crashing. What was supposed to happen was get a message from the client, if that message is equal to this, then send data back. However, the if function for if the message was correct wasn't firing, even though the message was correct.
Even when I remove the if function to check if the string was right or not, the program still freezes up. And by the way, my server is a console application, and my client is a SWT application.
Here's the server code with the removed if function:
try {
System.out.println("Waiting for a connection...");
// Start a server
ServerSocket server = new ServerSocket(3211);
// Listen for anyone at that port
Socket socket = server.accept();
System.out.println("The client has connected!");
// Get the data being sent in
DataInputStream inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
DataOutputStream ouputStream = new DataOutputStream(socket.getOutputStream());
// Turn that into UTF-8
String data = inputStream.readUTF();
System.out.println("Received " + data);
ouputStream.writeUTF("Great!");
System.out.println("Awesome!");
socket.close();
inputStream.close();
ouputStream.close;
server.close();
System.out.println("Socket closed\n-----------------------------");
}
catch(IOException e) {
System.out.println(e);
}
And the client (which is fired when a button gets pressed):
try {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnecting to the server...");
Socket socket = new Socket("192.168.1.206", 3211);
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnected to the server!");
DataInputStream input = new DataInputStream(System.in);
DataOutputStream output = new DataOutputStream(socket.getOutputStream());
output.writeUTF("sweet");
String data = input.readUTF();
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nSERVER: " + data);
input.close();
output.close();
socket.close();
}
catch (IOException er) {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\n" + er);
}
As soon as I press the button to try and start the connection (with the server already running), the client instantly freezes. It doesn't even send any of the "connecting to server" kind of stuff.
Any idea what's going wrong, and how to fix this?
Your client is reading from System.in. It should be reading from the socket input stream.
NB You only need to close the outermost output stream of a socket. That flushes it if necessary and closes the input stream and the socket. You're presently not only closing more than necessary but also in the wrong order,
Your socket is unable to send data because you did not called .flush() method on your outputstream reference. Use this one and you don't have to write flush() and close() method explicitely on streams
Server Code
System.out.println("Waiting for a connection...");
// Start a server
try (ServerSocket server = new ServerSocket(3211)) {
// Listen for anyone at that port
try (Socket socket = server.accept()) {
System.out.println("The client has connected!");
// Get the data being sent in
try (DataInputStream inputStream = new DataInputStream(new BufferedInputStream(socket.getInputStream()))) {
try (DataOutputStream ouputStream = new DataOutputStream(socket.getOutputStream())) {
// Turn that into UTF-8
String data = inputStream.readUTF();
System.out.println("Received " + data);
ouputStream.writeUTF("Great!");
System.out.println("Awesome!");
}
}
}
System.out.println("Socket closed\n-----------------------------");
} catch (IOException e) {
System.out.println(e);
}
Client Code
try {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnecting to the server...");
try (Socket socket = new Socket("127.0.0.1", 3211)) {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nConnected to the server!");
try (DataInputStream input = new DataInputStream(socket.getInputStream())) {
try (DataOutputStream output = new DataOutputStream(socket.getOutputStream())) {
output.writeUTF("sweet");
}
String data = input.readUTF();
System.out.println(String.format("data received from server '%s':\n", data));
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\nSERVER: " + data);
}
}
} catch (IOException er) {
allMessagesTextBox.setText(allMessagesTextBox.getText() + "\n" + er);
}
Output on Server
Waiting for a connection...
The client has connected!
Received sweet
Awesome!
Socket closed
-----------------------------
Output on Client
data received from server 'Great!':
Now moving to problem in your code.
See the client side code you have written DataInputStream input = new DataInputStream(System.in); instead of DataInputStream input = new DataInputStream(socket.getInputStream())
which causes the failure in receiving message from server
I am using Socketto send a task from one server to another like so:
private boolean sendRequest(String address, int port) {
boolean requestComplete = false;
try {
Socket socket = new Socket(address, port);
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject("task_to_complete");
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String msg = (String)ois.readObject();
if(msg.equals("complete")){
requestComplete = true;
}
ois.close();
oos.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
return requestComplete;
}
The second server receives the task like so:
while (true) {
// wait for connection
Socket socket = serverSocket.accept();
System.out.println("New connection accepted " + socket.getInetAddress() + ":" + socket.getPort());
// retrieve request from server
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
String msg = (String) ois.readObject();
switch (msg) {
case "task_to_complete":
// do task 1
break;
}
System.out.println("Task " + msg + " complete.");
// send a message back to client with the result of the task it
// requested
PrintWriter out =
new PrintWriter(socket.getOutputStream(), true);
out.print("complete");
ois.close();
socket.close();
}
But I get the error
java.io.EOFException at
java.io.ObjectInputStream$PeekInputStream.readFully(Unknown Source)
when I attempt to read the message "complete" from the first server:
ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());.
What is causing this error?
You messed up your protocol because
the server writes the response with PrintWriter.print("completed")
the client reads it with readObject()
I put a working demo on GitHub
try using
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String msg = in.readLine();
if(msg.equals("complete")){
requestComplete = true;
}
it worked for me in a similar situation
I'm working on a client-server file transfer project, I've almost completed my tests on localhost but today got an error below, here are the source codes of client and server:
Client side
public class Client {
public static void main(String args[]) {
String receiverIP = null;
int serverPort = 0;
receiverIP = args[0];
serverPort = Integer.parseInt(args[1]);
String fileToSend = args[2];
byte[] aByte = new byte[1];
int bytesR;
Socket clientSocket = null;
BufferedOutputStream bos = null;
InputStream is = null;
try {
clientSocket = new Socket(receiverIP, serverPort);
bos = new BufferedOutputStream(clientSocket.getOutputStream());
is = clientSocket.getInputStream();
} catch (IOException ex) {
ex.printStackTrace();
}
if (is != null) {
FileOutputStream fos = null;
ByteArrayOutputStream baos = new ByteArrayOutputStream();
try {
File myFile = new File( fileToSend );
System.out.println("The file chosen is being sent...");
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = null;
try {
fis = new FileInputStream( myFile );
} catch (FileNotFoundException ex) {
ex.printStackTrace();
}
try {
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray, 0, mybytearray.length);
bos.write(mybytearray, 0, mybytearray.length);
bis.close();
return;
}catch (IOException ex) {
ex.printStackTrace();
}
File file = new File("C:\\copy.jpg");
fos = new FileOutputStream( file );
bos = new BufferedOutputStream(fos);
bytesR = is.read(aByte, 0, aByte.length);
do {
baos.write(aByte);
bytesR = is.read(aByte);
} while (bytesR != -1);
System.out.println("File transfer successful");
bos.write(baos.toByteArray());
bos.flush();
bos.close();
clientSocket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
Server side
public class Server {
public static void main(String args[]) {
while (true) {
ServerSocket welcomeSocket = null;
BufferedOutputStream ToClient = null;
try {
welcomeSocket = new ServerSocket(3249);
System.out.println("The port " + welcomeSocket.getLocalPort() + " is opened and ready for use.");
Socket connectionSocket = welcomeSocket.accept();
ToClient = new BufferedOutputStream(connectionSocket.getOutputStream());
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}
here is the error I get
The file chosen is being sent...
java.net.SocketException: Connection reset by peer: socket write error
at java.net.SocketOutputStream.socketWrite0(Native Method)
at java.net.SocketOutputStream.socketWrite(Unknown Source)
at java.net.SocketOutputStream.write(Unknown Source)
at java.io.BufferedOutputStream.write(Unknown Source)
at Client.main(Client.java:44)
java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at Client.main(Client.java:55)
I'm nearly sure this error is not about closing the server socket before all data is transmitted, and about the reading and writing process on the bytearray but all my fix attempts were in vain, maybe I've misplaced the streams so they do not work as intended, (the copy.jpg file is created but not getting any streams) any help would be appreciated
edit: I forgot to mention, currently I'm using a wireless internet connection and I've read a little about socket porgramming that mentions wireless networks are unreliable to test on
Your server side does not wait for data to be received. It accepts the connection and then continues with the next loop cycle immediately. This causes your initial server socket and socket to client to be garbage-collected and thus closed.
You can verify this behaviour by using telnet, which is very handy when it comes to checking servers in general. Open a command prompt on the server machine (cmd or a console) and run this command to connect to your server:
telnet localhost 3249
You will see that it connects and then gets disconnected almost immediately, just like your own client application.
The solution is that additionally to the code for accepting the connection on the server side, you need to write code there for receiving the data.
Moreover, you should put the creation of the server socket in front of the loop instead of inside the loop. You need to create the server socket only once and you can then accept arbitrarily many connections through it. Opening the server socket more than once will fail, because the port is still occupied (freeing the port often takes a few seconds in some operating systems, even when the previous server socket has been closed).
Client code:
try {
Socket socket = new Socket(ip, port);
OutputStream output = socket.getOutputStream();
ObjectOutputStream out = new ObjectOutputStream(output);
InputStream input = socket.getInputStream();
ObjectInputStream in = new ObjectInputStream(input);
out.writeByte(1);
FileHandler fh = (FileHandler) in.readObject();
//processing stuff
out.flush();
out.close();
output.flush();
output.close();
input.close();
in.close();
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
Server code:
try {
ServerSocket server = new ServerSocket(port);
Socket socket = server.accept();
InputStream input = socket.getInputStream();
ObjectInputStream in = new ObjectInputStream(input);
int type = in.readByte();
//processing stuff (which includes closing the streams and sending FileHandler object)
socket.close();
} catch (Exception e) {
e.printStackTrace();
}
The server never receives the byte. It just waits for the byte from the client, and it never comes. I'm not sure why it isn't sending, or getting received. Any help is much appreciated.
If I had to make a guess it's because in your client you block on in.readObject(); waiting for the server to send you something thus never flush the output stream thus ... nothing ever gets sent.
Move your read to after you flush your output stream.
Try to use the writeObject and readObject methods. Also write an Integer not an int to the stream. Read this really good lecture before proceeding any further.
This is also a good lecture for your problem.
Regards!
I have a written a simple Client-Server pair, sending an Object to the server. I have tested the code and it works, provided I use LOCALHOST as the server name.
When attempting to connect to the server using my own IP address, the client continuously times out. I cannot help thinking I've missed a trick, if someone could take a look at the code I would be very grateful. Many Thanks, J.
client
ObjectOutputStream oos = null;
ObjectInputStream ois = null;
Socket socket = null;
Person p = null;
try {
// My IP address entered here..
socket = new Socket("xx.xx.xxx.xxx", 3000);
// open I/O streams for objects
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
/*
// read an object from the server
p = (Person) ois.readObject();
System.out.print("Name is: " + p.getName());
oos.close();
ois.close();*/
//write object to the server
// p = new Person("HAL");
oos.writeObject(new Person("HAL"));
oos.flush();
ois.close();
oos.close();
} catch(Exception e) {
System.out.println(e.getMessage());
}
Server
public Server() throws Exception {
server = new ServerSocket(3000);
System.out.println("Server listening on port 3000.");
this.start();
}
You either need to make your server bind to 0.0.0.0 (wildcard, all interfaces on your machine) or the specific IP you want it to listen on. The ServerSocket constructor you're using only takes a port number and binds to localhost which is going to resolve to 127.0.0.1
server = new ServerSocket(3000, 5, InetAddress.getByName("0.0.0.0"));
Edit to add: The second paramater is the backlog size. This is the number of connections that can be queued waiting for you to accept() them before additional connection attempts will result in "connection refused".