I am feeling really stupid right now guys.... basically I am connecting over TCP on a local machine... and when I try to make the In/out streams at the client it wont get passed creating the object input stream. What gives? This stops after printing 2... no exceptions or anything... This isn't the first time I've used this class which is partialy why I am puzzled.
try {
System.out.println("1");
mySocket = new Socket("localhost", 11311);
System.out.println("12");
oos = new ObjectOutputStream(mySocket.getOutputStream());
System.out.println("2");
ois = new ObjectInputStream(mySocket.getInputStream());
System.out.println("13");
} catch (Exception e) {
e.printStackTrace();
}
From the specification of ObjectInputStream:
This constructor will block until the corresponding ObjectOutputStream
has written and flushed the header.
(For future readers:) I had the same problem because i made a silly change in server program and didn't test it for a long time then i was confused about why program is locked.
ServerSocket accepts the connection (responderSocket = serverSock.accept();) then suddenly for a inapropriate if (The silly change i mentioned!) program jumps out of the thread and because i didn't add a finally block to close streams and sockets the socket was left abandoned w/o sending or recieving anything (even stream headers). So in client side program there was no stream header (When i debbugged The code i saw that the last function executed before lock was:
public ObjectInputStream(InputStream in) throws IOException {
verifySubclass();
bin = new BlockDataInputStream(in);
handles = new HandleTable(10);
vlist = new ValidationList();
enableOverride = false;
readStreamHeader(); //// <== This function
bin.setBlockDataMode(true);
}
readStreamHeader();)
So be careful about what happens in server side, maybe problem isn't where you expecting it!
Related
I am learning about sockets in java, but when I was running a program that sends messages from the client side to server side it doesn't show a message. If I enter some text on the client side it doesn't show up on the server side, but if I type endProcess it stops running. Which means that the message is going through it's just not showing up.
My Client.java code is here:
import java.net.*;
import java.io.*;
public class Client{
Socket soc;
DataInputStream dis;
DataOutputStream dos;
public Client(){
try{
soc = new Socket("(Address)",5000);
System.out.println("Connection Established");
dis = new DataInputStream(System.in);
dos = new DataOutputStream(soc.getOutputStream());
System.out.println("Streams connected");
}catch(UnknownHostException u){
System.out.println(u);
}catch(IOException i){
System.out.println(i);
}
String line = "";
while(!line.equals("endConnection")){
try{
line = dis.readUTF();
dos.writeUTF(line);
}catch(IOException i){
System.out.println(i);
}
}
try {
soc.close();
dis.close();
dos.close();
} catch (Exception e) {
System.out.println(e)
}
}
public static void main(String[] args) {
new Client();
}
}
Here is my Server.java code:
import java.net.*;
import java.io.*;
public class Server {
ServerSocket serSoc;
Socket soc;
DataInputStream dis;
public Server(){
try {
serSoc = new ServerSocket(5000);
System.out.println("Server Online");
soc = serSoc.accept();
System.out.println("Client Connected");
dis = new DataInputStream(new BufferedInputStream(soc.getInputStream()));
String line = "";
System.out.println("Waiting for input...");
while(!line.equals("endConnection")){
line = dis.readUTF();
System.out.println(line);
}
System.out.println("Client disconnected");
soc.close();
dis.close();
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
new Server();
}
}
There are many problems here.
Duplex protocol issues
line = dis.readUTF();
dos.writeUTF(line);
This isn't going to work; The dis.readUTF() line is going to block (freeze) until a line is read. The problem is, sometimes you have nothing to send in which case you want to read, and something you have nothing to read in which case you want to send. In practice you need to redesign this entirely; you need 2 threads. At which point you get into the issues of multicore, needing synchronization primitives and/or java.util.concurrent classes for all data that is shared between the 2 threads.
Alternatively, adopt a model that is strictly push or pull (where at any given time both parties already know who can send, and if the other party wants to send they simply cannot. For example, every party sends a simply 'NOTHING TO DO' message every second, trading places every time. This is quite an inefficient algorithm, of course. But could be written without involving multiple threads.
Flush and close issues
dos.writeUTF(line);
This doesn't actually send anything, or at least, isn't guaranteed to. To send any data on the internet, it gets wrapped in a packet which has lots of overhead. So, things are buffered until there's a full packet to send. Which means that line doesn't do anything. It just fills a buffer, no packets go out. You first need to close or flush. dos.flush() would help maybe. This is a big problem, because later you do:
soc.close();
dis.close();
dos.close();
You first close the socket, which, well, closes the socket. You then close the streams, which will also send anything that's still stuck in a buffer, except, that will fail, because the socket is already closed. In other words, the line you .writeUTF()-ed? It never gets there. You first shove it in a buffer, then you close the socket, then you send the buffer which won't work as the socket is already closed.
Broken error handling
} catch (Exception e) {
System.out.println(e);
}
Horrible. Don't do this. Your code reacts to any problem by printing something and just keeping right on going. That means if anything goes wrong, the client will start spamming an endless cavalcade of exception traces and locking up the system with any luck. You want the code to stop running when problems occur. Easiest way, by far, is to just stick throws IOException on your constructor and main method, which is allowed. Distant second best option is to configure your 'eh whatever' catch blocks as throw new RuntimeException("unhandled", e); instead of e.printStackTrace().
What you do (System.out.println(e);) is even worse - you are tossing away extremely useful information such as the stack trace and causal chain.
My problem is when it tries to read the object the second time, it throws the exception:
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at Client.run(BaseStaInstance.java:313)
java.io.StreamCorruptedException: invalid type code: AC
at java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1356)
at java.io.ObjectInputStream.readObject(ObjectInputStream.java:351)
at Client.run(BaseStaInstance.java:313)
The first time I send the exact same object message; however, when I try doing the same thing the second time, it throws the error above. Do I need to re-intialize the readObject() method? I even printed out the message object that is being received by the line below and its exact the same as the first instance where it works ok.
Object buf = myInput.readObject();
I'm assuming there's some problem with appending, but I really have no use for appending. I just want to read a fresh line everytime.
I'd really appreciate some help in fixing this bug. Thank you.
==================================
Before that one line, I'm just creating the input and output objects for the socket in the run() method. The object declaration is outside the run() method in the class:-
#Override
public void run() {
try {
sleep((int) 1 * 8000);
} catch (Exception e) {
e.printStackTrace();
}
try {
//Creating input and output streams to transfer messages to the server
myOutput = new ObjectOutputStream(skt.getOutputStream());
myInput = new ObjectInputStream(skt.getInputStream());
while (true) {
buf = myInput.readObject();
}
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
} catch (Exception e) {
e.printStackTrace();
}
}
}
You're right; I don't close the object. I'm not sure how to do that.
The underlying problem is that you are using a new ObjectOutputStream to write to a stream that you have already used a prior ObjectOutputStream to write to. These streams have headers which are written and read by the respective constructors, so if you create another ObjectOutputStream you will write a new header, which starts with - guess what? - 0xAC, and the existing ObjectInputStream isn't expecting another header at this point so it barfs.
In the Java Forums thread cited by #trashgod, I should have left out the part about 'anew for each object at both ends': that's just wasteful. Use a single OOS and OIS for the life of the socket, and don't use any other streams on the socket.
If you want to forget what you've written, use ObjectOutputStream.reset().
And don't use any other streams or Readers or Writers on the same socket. The object stream APIs can handle all Java primitive datatypes and all Serializable classes.
I am stuck with this very strange problem. In the client I am passing in objects like
try{
oos.writeObject(new GameStartSerializedObject());
oos.flush();
}
catch(Exception e){
e.printStackTrace();
}
and in the server I am reading the object
try{
//Its my turn
thrown_message = player_reader.readObject();
}
catch(Exception e){
My question is why am i getting EOF exception. My understanding of object input stream is when i call readObject() i should block until i get an object so how does it know if the eof is reached? Please help!
This is how I create object streams
ois = new ObjectInputStream(socket.getInputStream());
oos = new ObjectOutputStream(socket.getOutputStream());
oos.flush();
Also, after i write object and flush should i close the stream. I am not closing it since the objects are written pretty regularly from different parts of the code one after another.
The peer has closed the connection. Ergo there are no more objects to read. Ergo you have reached the end of the stream. Ergo readObject() throws EOFException.
I've got a client-server app I'm making and I'm having a bit of trouble when reading objects on the server.
After my server connects to a client socket, I build object input and output streams and pass them along to my service() method. In there, I'm supposed to handle different kinds of messages from the client. I can get a message from the client (that is, a Message object, of my design) just fine. But of course, what I want to do is have a loop so I can get a message, process it, and respond back.
So far, my code only works for a single message. When I added my loop, what happened was on every iteration, my server just kept reading the same message over and over again before my client got a chance to send a new message over the socket (I think this is what's happening, at least).
So what I really need to do is figure out how to make my service() method wait for new input. Any ideas? Or am I approaching this wrong? Do I need to create a new OIS on every iteration or...? Some code:
public void service(ObjectInputStream input, ObjectOutputStream output) throws IOException, Exception {
_shouldService = true;
while (_shouldService) {
// It just keeps reading the same message over and over
// I need it to wait here until the client sends a new message
// Unless I'm just approaching this all wrong!
NetworkMessage message = (NetworkMessage) input.readObject();
NetworkMessageHeader header = message.getHeader();
String headerType = header.getType();
if (headerType.equals(NetworkMessageHeader.NetworkMessageHeaderTypeConnect)) {
doLoginForMessage(message, output);
} else if (headerType.equals(NetworkMessageHeader.NetworkMessageHeaderTypeFiles)) {
doFilesList(message, output);
} else {
System.out.println("Unrecognized header type: " + headerType);
}
}
}
The ObjectOutputStream caches object representations and will not detect if you are resending the same instance over and over again from the client side, but with changes in it. If this is your scenario you need to call reset on the stream before each send.
NetworkMessage message = new NetworkMessage();
for(;;) {
message.setProperty(whatever);
oos.reset();
oos.writeObject(message);
}
I'm currently using a Java implementation of the Reliable UDP protocol, found [here][1]. The project has absolutely no tutorials so I have found it really hard to identify problems.
I have set up a client and server. The server runs on localhost:1234 and the client runs on localhost:1235. The server is first established, and loops listening for connections.
I then have set it to send a packet to the server. When a packet is sent, the server calls handlePacket() -
DataInputStream i = new DataInputStream(client.getSocket().getInputStream());
short packetID = i.readShort();
i = null;
switch(packetID){
case 3:
Packeta packeta = new Packeta(client);
break;
}
} catch (IOException e) {
e.printStackTrace();
}
I'm currently using a debugging with a small dummy class called Packeta. When the constructor is called, it reads from a stream and the logs to the console. However, always when constructing, it hangs for 10 seconds, before producing the error -
java.net.SocketException: Socket is closed ....
at
lessur.engine.net.packets.Packeta.(Packeta.java:15)
The constructor for Packeta -
public Packeta(LessurConnectedNode c) {
super((short)3, c);
try {
/*LINE 15*/ Logger.getLogger("adsfas").info("X was "+c.getSocket().getInputStream().read());
} catch (IOException e) {
e.printStackTrace();
}
}
It has something todo with the input streams. I don't know what is wrong, but from reading other threads, it might be todo with having multiple inputstreams. I'm lost on this, please help.
The problem was, I was passing the server to the socket listener, before the socket was fully initialized. FIXED!