I am writing server-client application. Client sends some sort of data via different streams to the server. Once I place streams like this in the main method the program does nothing; no exception just empty console:
try {
socket = new Socket("localhost", 4050);
din = new DataInputStream(socket.getInputStream());
oin = new ObjectInputStream(socket.getInputStream());
dout = new DataOutputStream(socket.getOutputStream());
} catch (UnknownHostException e) {
System.out.println("Exception: the host is unknown");
} catch (IOException e) {
System.out.println("I/O exception thrown by socket");
}
Once I remove this stream oin = new ObjectInputStream(socket.getInputStream()); from that part of main method the program throws EOFException or connection reset exception.
What is so special in the above code that the program does nothing and throws no exceptions?
Once you place the mentioned stream in to a separate method
private static MessageObject readObject(){
MessageObject mo = null;
try{
oin = new ObjectInputStream(socket.getInputStream());
mo = (MessageObject)oin.readObject();
}
catch(IOException e){
System.err.println(e.getCause());
}
catch(ClassNotFoundException e){
System.err.println(e.getCause());
}
return mo;
}
It throws this exception:
Exception in thread "main" java.net.SocketException: Connection reset
at java.net.SocketInputStream.read(Unknown Source)
at java.net.SocketInputStream.read(Unknown Source)
at java.io.DataInputStream.readBoolean(Unknown Source)
at Server.main(Server.java:77)
On the server it is on the if branch:
if (din.readBoolean()) {
ObjectInputStream oin = new ObjectInputStream(s.getInputStream());
MessageObject o = (MessageObject)oin.readObject();
// server saves the whole thing
MessageDB.add(o);
}
I can't place here all my code, it is my assignment.
ooops, sorry people, the mistake has been found. Some logical mistake, the server was expecting some input,but the client was refusing to send it.
You are making several mistakes here.
You are using multiple streams over the same socket. Don't do that, they will only confuse each other. As you need object I/O, just use an ObjectInputStream and ObjectOutputStream for everything.
Incorrect construction order. You must construct the ObjectOutputStream before the ObjectInputStream, at both ends.
You are using streams with different lifetimes. You haven't hit the problem yet but eventually this will lead to a StreamCorruptedException. Use the same ObjectInputStream and ObjectOutputStream for the life of the Socket, at both ends.
You probably also need to read the Javadoc for ObjectOutputStream.reset() and .writeUnshared() to understand what they do, and why you might need to call one or the other of them.
Related
This question already has answers here:
ObjectInputStream/ObjectOutputStream work not right
(3 answers)
Closed 7 years ago.
I have this server/client model for a game but it keeps getting stuck at the ObjectInputStream initialization.
Here is the code for the client's start method:
public void start(){
try {
Socket s = new Socket("127.0.0.1", 24680);
Thread.sleep(1000);
ois = new ObjectInputStream(s.getInputStream()); // stuck here
oos = new ObjectOutputStream(s.getOutputStream());
startGame();
} catch (Exception e) {
e.printStackTrace();
}
}
}
here is the server code:
try {
InputStream fis = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(fis);
while (true) {
ArrayList < Dot > lists = (ArrayList < Dot > ) ois.readObject();
for (Socket s: sockets) {
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(lists);
}
}
} catch (Exception e) {
e.printStackTrace();
}
Thanks in advance!
You need to construct the ObjectOutputStream before the ObjectInputStream at at least one end, preferably both to avoid accidents. Otherwise new ObjectInputStream() blocks trying to read the stream header which hasn't been written yet by the peer's new ObjectOutputStream(), because he also is blocked in new ObjectInputStream().
Other notes:
You must use the same object streams for the life of the socket, at both ends, unlike your current code. The reason is the same: the stream header. If you keep creating new ObjectOutputStreams you will keep writing new stream headers, which the peer won't expect or understand.
Remove the sleep(). There is no need for sleeps in networking code. They are just literally a waste of time. Cargo-cult programming.
I am writing Socket program , Here Client Sends a String through Stream , Server Process it and writes back to Client. My problem is, after Server process the String , it Writes back to Stream but in client It can't able to read the Stream its showing exception as Exception in while: java.net.SocketException: socket closed Here is my code,
Client ,
public void run() {
while (true) {
try {
// Open your connection to a server, at port 1231
s1 = new Socket("localhost", 1231);
OutputStream s1out = s1.getOutputStream();
DataOutputStream dos = new DataOutputStream(s1out);
InputStream in=s1.getInputStream();
DataInputStream dis=new DataInputStream(in);
String s = br.readLine();
dos.writeUTF(s);
dos.flush();
dos.close();
System.out.println(dis.readUTF());//it is the String from Server after processing
dis.close();
} catch (IOException ex) {
// Logger.getLogger(SimpleClient.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Exception in while: " + ex);
}
}
In Server
public void run()
{
while(true){
try {
System.out.println("Waiting for connect to client");
s1=serverSocket.accept();
s1In = s1.getInputStream();
dis = new DataInputStream(s1In);
out=s1.getOutputStream();
dos=new DataOutputStream(out);
String clientData=dis.readUTF();
//processing task String
dos.writeUTF("Bus Registered Successfully");
dos.flush();
}
}
Here I am not able to read Bus Registered Successfully at client side . How to Solve this.?
Well there are many things not right in your program. But first let me answer your question ... you are closing the socket just after writing the stream ... so server throws exception, just remove dos.close(); just after the dos.flush();. It will run fine.
Now back to the programming practices ...
1) Server should accept the connection in a while(true) loop and then make a new thread. So following statement should not be the part of run method.
System.out.println("Waiting for connect to client");
s1=serverSocket.accept();
s1In = s1.getInputStream();
dis = new DataInputStream(s1In);
out=s1.getOutputStream();
dos=new DataOutputStream(out);
2) There is no need of run method in client. Because Every new client will be a new program that has its own variables and socket.
A quick look shows me that the reason the socket is closed is because you used dos.close().
Closing a DataInputStream (or PrintStream, or any similiar stream) will close the underlying socket.
Just take out dos.close().
You can also move the dos.close() to the very end of the try block. As a general rule, don't close anything related to the socket until you're done with the socket.
This is my code. When I run this, I get up to "Three and a Half" printed. (The prints are added for debugging since I don't know any other way.) After that, the execution hangs. No exceptions, no prompts, nothing. So what is wrong with my object creation? Each and every tutorial I see online has the same code, but mine won't work.
public class Connection {
Socket socket;
ObjectInputStream iStream;
ObjectOutput outputStream;
public Connection(Socket s) {
try {
System.out.println("One");
socket = s;
System.out.println("Two");
outputStream = new ObjectOutputStream(new BufferedOutputStream(socket.getOutputStream()));
System.out.println("Three");
InputStream is = socket.getInputStream();
System.out.println("Three and a Half");
iStream = new ObjectInputStream(is);
System.out.println("Four");
} catch (IOException e) {
e.printStackTrace();
}
}
}
Thanks in advance.
It's in the Javadoc:
A serialization stream header is read from the stream and verified. This constructor will block until the corresponding ObjectOutputStream has written and flushed the header.
So the new ObjectInputStream is hanging because it's waiting on input. You need to create an ObjectOutputStream and send data through the socket.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
java.net.SocketException: Software caused connection abort: recv failed
I'm trying to write a client server pair where the connection is live all day and the client waits for the server to send a message. The steps are:
Server opens port and listens for connection
Client connects in and waits for data
Some time later (maybe hours) the server sends data to the client
Client processes data and returns it to the server
Repeat steps 3 and 4
I can get steps 1-4 working, however if I try to repeat step 3 I get the error in the title.
This is my method on the client side:
private static void waitForInput(SSLSocket sslsocket) throws IOException {
do {
try {
ObjectInputStream ois = new ObjectInputStream(sslsocket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(sslsocket.getOutputStream());
Object o = (Object) (ois.readObject());
// excluded code to process data
oos.flush();
oos.writeObject(o);
oos.reset();
}
catch(ClassNotFoundException e){
System.err.println(e.getMessage());
}
} while ( true );
}
The code fails on the 4th line, The first time around it blocks and waits until I get the next bit of data, but it doesn't work twice. What am I doing wrong?
Connection abort IOException is thrown when you are waiting to read from a socket that has been closed at the other end, check to see your server side code , if you are not accidentally closing the socket.
Also the server side code could be uploaded for deeper analysis, also try posting the stack trace, it will help analyzing.
You could move the declaration for ois and oos out of the do ... while loop, since there is no need to redeclare them everytime, might need a try ... catch around that.
private static void waitForInput(SSLSocket sslsocket) throws IOException {
ObjectInputStream ois = new ObjectInputStream(sslsocket.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(sslsocket.getOutputStream());
do {
try {
Object o = (Object) (ois.readObject());
// excluded code to process data
oos.writeObject(o);
oos.flush();
}
catch(ClassNotFoundException e){
System.err.println(e.getMessage());
}
} while ( true );
}
And I have removed the oos.reset(); and moved the oos.flush();
I believe that the problem is the oos.reset(); and i would never reset a connection that is supposed to be persistent for hours, or, at least part of it.
Besides there is already a ois for that connection and you don't need two of them.
I'm doing my own server in Java. I need to do one socket connection and receive a lot of object from client. I did it, it works, but I don`t know if this is the best(fastest) solution. Here is example of my code:
try {
serverSocket=new ServerSocket(18234, 1000);
} catch (IOException e) {
System.out.print("Server failed..");
e.printStackTrace();
}
Object x;
ObjectInputStream ois;
System.out.println("Waiting for connection...");
Socket connection= serverSocket.accept();
System.out.println("Connection received from " + connection.getInetAddress().getHostName());
while(true){
ois = new ObjectInputStream(connection.getInputStream());
x=ois.readObject();
System.out.println(x.getString());
if(x.getString().equals("END")) break;
}
Problem is, that when I try receive new object, all time I must do new ObjectInputStream.. Is this solution correct? I must do really fast server and all time doing new ObjectInputStream is too expensive in my opinion.
Use the same ObjectOutputStream and ObjectInputStream for the life of the socket, at both ends. Your statement about being obliged to use a new one each object is incorrect.