I've the following code:
public class SenderTask implements Runnable {
private DhtDto dto;
private ObjectOutputStream oos = null;
private Socket socket = null;
public SenderTask(DhtDto dto){
this.dto = dto;
}
#Override
public void run() {
try{
socket = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),dto.sendTo());
oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(dto);
oos.close();
socket.close();
oos.reset();
}catch(IOException e){
Log.e("sender","IOException: ",e);
}
}
}
I'm getting a StreamCorruptedException at the following line:
oos.writeObject(dto);
When I searched, I saw answers saying that I should use only one ObjectOutputStream throughout the lifecycle of socket. But I don't understand what this exactly means. Can someone elaborate on what is the problem here and how to resolve it?
Thanks in advance.
Finally, I've resolved it with some help from a classmate. The idea was to use a BufferedOutputStream in middle of Sockets and ObjectOutputStream. I don't properly know the reason though.
Related
Greeting,
I am working on a program that depends on p2p local network ,i create new peers by pressing run on the IDE , i want an array list to be shared between all the threads so i can modify on it.
the problem i have faced that if the first thread write on the serialization file the newly created threads can read this modification on the list, but if the last thread modify the list the first threads can't see this modification since they desesrialize the file once on the run button press.
is there any solution for this ?(Java)
code:
Peer peer = Peer.getInstance(portName, portNumber, "localhost", peers);
new Thread(peer::startHost).start();
peers.put(peer.getPort(), peer);
waitASecond();
serializePeers();
return peer;
Serialize :
private static void serializePeers() {
try {
FileOutputStream fos = new
FileOutputStream("peersList.ser");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(peers);
oos.close();
fos.close();
} catch (IOException ioe) {
ioe.printStackTrace();
}
}
Desirialize:
private static void deserializePeers() {
try {
FileInputStream fis = new FileInputStream("peersList.ser");
ObjectInputStream ois = new ObjectInputStream(fis);
peers = (LinkedHashMap<Integer, Peer>) ois.readObject();
ois.close();
fis.close();
} catch (Exception e) {
System.out.println("This is the first peer connected to the network"); }
}
I am going to write a program over TCP/IP and I should send objects by client or by server, It is going right when I want to send or receive strings but when I am trying to read an object:
private Socket client;
public ThreadedClient(Socket client) {
this.client = client;
}
#Override
public void run() {
try {
ObjectInputStream objIn = new ObjectInputStream(client.getInputStream());
while(true){
try {
Object fromClient = objIn.readObject();
} catch (ClassNotFoundException e) {e.printStackTrace();}
}
} catch (IOException e) {e.printStackTrace();}
}
I receive an exception:
java.io.StreamCorruptedException: invalid stream header: 306E6165
at java.io.ObjectInputStream.readStreamHeader(Unknown Source)
at java.io.ObjectInputStream.<init>(Unknown Source)
at org.bihe.serverSocket.ThreadedClient.run(Server.java:137)
at java.lang.Thread.run(Unknown Source)
and it refers to this line:
ObjectInputStream objIn = new ObjectInputStream(client.getInputStream());
It is my server code:
ServerSocket ss = new ServerSocket(8800);
while(true){
Socket newClient = ss.accept();
System.out.println(">>>> Client number " + (++counter) + " connected.");
OutputStream outputStream = newClient.getOutputStream();
PrintWriter sender = new PrintWriter(outputStream);
sender.println(true);
sender.flush();
ThreadedClient client = new ThreadedClient(newClient);
clients.add(client);
new Thread(client).start();
Client side code:
sc = new Socket("127.0.0.1", 8800);
InputStream inputStream = sc.getInputStream();
Scanner scanner = new Scanner(inputStream);
boolean s = scanner.nextBoolean();
if(s){
System.out.println("Client connected successfully.");
return true;
}else{
System.out.println("Ohhh, Some problem happened, try again later!");
}
Can anyone explain me what is happening, what is this exception and why I received this exception?
If you want to send object over network you must serialize your objects.
Check this question:
How To send an object over TCP in Java
Java Serialization:
Serialization
You could do it like this:
import java.net.*;
import java.io.*;
class testobject implements Serializable {
int value;
String id;
public testobject(int v, String s ){
this.value=v;
this.id=s;
}
}
public class SimpleServer {
public static void main(String args[]) {
int port = 2002;
try {
ServerSocket ss = new ServerSocket(port);
Socket s = ss.accept();
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
testobject to = (testobject)ois.readObject();
if (to!=null){System.out.println(to.id);}
System.out.println((String)ois.readObject());
is.close();
s.close();
ss.close();
}catch(Exception e){System.out.println(e);}
}
}
import java.net.*;
import java.io.*;
public class SimpleClient {
public static void main(String args[]){
try{
Socket s = new Socket("localhost",2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
testobject to = new testobject(1,"object from client");
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);}
}
}
Just get rid of sending and receiving the Boolean. It's redundant. If there was some problem creating the connection, the socket wouldn't get created: an exception would be thrown instead. You're confusing everything with multiple streams on the same socket. Don't do that.
In your read-object loop, you need to catch EOFException separately, and when you get it, close the socket and exit the loop. If you get any other IOException, log it, close the socket, and exit the loop.
If you'd like to achieve good performance and send object then you definitely should use Google Protobuf
It allows you to define messages in simple .proto files. Then you use bundled compiler to generate Java classes which will be serialized and sent.
Also better idea is to use Netty over plain Java sockets. This prevent you from writing a lot of boilerplate code and define simple serialization/deserialization pipelines. Take a look at user-guide.
I get this exception while trying to send objects over UDP socket in java
java.io.StreamCorruptedException: invalid stream header: 00000000
Here is the code for sender: `
public class Epl_Client implements Serializable{
public static void main(String[] args )
{
try{
ParseMessage pm = new PaseMessage();
DatagramSocket Sock;
Sock = new DatagramSocket();
DatagramPacket Dp;
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(4 * 1024);
ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
objectOutputStream.writeObject(lg);
byte[] objectBytes = byteArrayOutputStream.toByteArray();
Dp = new DatagramPacket(objectBytes, objectBytes.length,InetAddress.getByName("localhost"),9876);
Sock.send(Dp);
Sock.close();
}
catch (Exception e){
System.out.println("exception caught" + e);
}
}}
Code for receiver :
public class ClassServer{
public static void main(String[] args){
ParseMessage pm=new ParseMessage();
try{
byte[] recvBuf = new byte[5000];
while(true){
DatagramSocket serverSocket = new DatagramSocket(9876);
ByteArrayInputStream bais = new ByteArrayInputStream(recvBuf);
ObjectInputStream objectInputStream = new ObjectInputStream(bais);
pm= (ParseMessage)objectInputStream.readObject();
System.out.println(pm.message);
bais.close();
objectOutputStream.close();
}
}
catch(Exception e)
{
System.out.println("Exceptiom"+e);
}
}}
And the class
public class ParseMessage implements Serializable{
String message;
public ParseMessage()
{ message="Inavalid";}}
Can anyone help to resolve this error?
You're never actually receiving anything from the socket. Look at your code - you create a DatagramSocket and then never refer to it again. You're always building a ByteArrayInputStream wrapping an array full of zeroes.
You need to call DatagramSocket.receive, and then use the length of the received data when constructing a ByteArrayInputStream. However, you'll need to be certain that you can fit all the data in a single packet. Are you sure you don't want a stream-based protocol?
Im trying to reconstruct a serialized object and access data from it.
This is how Im sending the object.
Socket socket = new Socket ("localhost", port);
ObjectOutputStream out = new ObjectOutputStream (socket.getOutputStream());
Tester t = new Tester("test");
out.writeObject(t);
out.flush();
And this is how I'm receiving it
// This is how the server is being built
private ServerSocket server;
server = new ServerSocket(port);
newsocket = server.accept();
// And this is how Im actually getting the object
ObjectInputStream input = new ObjectInputStream(newSocket.getInputStream());
Tester obj = (Tester) input.readObject();
System.out.println(obj.getText());
However I only get the following output
[Ljava.lang.StackTraceElement;#237360be
What I was hoping to get was the string I sent in the object "Test". Is there anything Im doing wrong?
My Tester class looks like this
public class Tester implements Serializable {
private String theMessage = "";
public Tester(String message) {
theMessage = message;
}
public String getText() {
return theMessage;
}
}
Try this
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ObjectOutputStream oos = new ObjectOutputStream();
Tester tester0 = new Tester("test")
oos.writeObject(tester0);
oos.close();
System.out.println(tester0.getText());
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));
Tester tester = (Tester) ois.readObject();
System.out.println(tester.getText());
If this doesn't work, you may have a bug in your serialization code.
It seems, that you had wrapped code-block of socket listener into try...catch statement, where you are using some logger in catch part in an incorrect way: it prints the stacktrace instead of printing the error cause. This is the most probable explanation, why you receive [Ljava.lang.StackTraceElement;....
Indeed your socket-listener code catches some Exception, which you have to print in an appropriate way.
I need to build an app where I have four servers running and one client send some packages to these servers, but these servers have to keep running all the time receiving something from the client(sender).
So I create the both classes, client and server:
public class Server {
public Event receive(int port) {
Evento event = null;
try {
ServerSocket ss = new ServerSocket(port);
Socket s = ss.accept();
InputStream is = s.getInputStream();
ObjectInputStream ois = new ObjectInputStream(is);
evento = (Evento) ois.readObject();
is.close();
s.close();
ss.close();
}catch(Exception e){
System.out.println(e);
}
return event;
}
}
public class Client {
public void send(Event event, int port) {
try {
Socket s = new Socket("localhost", 2002);
OutputStream os = s.getOutputStream();
ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(event);
oos.close();
os.close();
s.close();
} catch (Exception e) {
System.out.println(e);
}
}
}
But as I said, I need these servers keep running all the time, if I test once, that's ok, but twice or more, don't.
How could I do that ?
The standard pattern is to create one thread for each connection. If you use one thread you can only read from one blocking connection.
just add a do while block around the readObject.
As a break condition you can check whether the message is something like "exit"..
cheers