I'm working on a school project and the following codes are an example provided for building the project (should work without any problem but not...). There was no compiling error but when I use telnet to test it the following message shows:
java.io.StreamCorruptedException: invalid stream header: 56543130
at java.io.ObjectInputStream.readStreamHeader(ObjectInputStream.java:801)
at java.io.ObjectInputStream.<init>(ObjectInputStream.java:298)
at ThreadedDataObjectHandler.run(ThreadedDataObjectServer.java:41)
Line 41 is
ObjectInputStream in =new ObjectInputStream(incoming.getInputStream());
Here are my codes:
import java.io.*;
import java.net.*;
import java.util.*;
public class ThreadedDataObjectServer {
public static void main(String[] args ) {
try
{ ServerSocket s = new ServerSocket(3000);
for (;;)
{ Socket incoming = s.accept( );
new ThreadedDataObjectHandler(incoming).start();
}
}
catch (Exception e)
{ e.printStackTrace();
}
}
}
class ThreadedDataObjectHandler extends Thread
{
DataObject myObject = null;
private Socket incoming;
private String greeting="Hello!";
public ThreadedDataObjectHandler(Socket incoming)
{
this.incoming = incoming;
}
public void run()
{ try
{
ObjectInputStream in =new ObjectInputStream(incoming.getInputStream());
ObjectOutputStream out =new ObjectOutputStream(incoming.getOutputStream());
myObject = (DataObject)in.readObject();
System.out.println("Message read: " + myObject.getMessage());
myObject.setMessage("Got it!");
System.out.println("Message written: " + myObject.getMessage());
out.writeObject(myObject);
in.close();
out.close();
incoming.close();
}
catch (Exception e)
{ e.printStackTrace();
}
}
}
class DataObject implements Serializable{
protected String message;
public DataObject(){
message="";
}
public void setMessage(String m){
message=m;
}
public String getMessage(){
return message;
}
}
What I tried was to switch the order of statements ObjectInputStream in=... and ObjectOutputStream out=... but no luck. Please help...thanks.
From what I understood from the comments you are trying to read the objects from a telnet connection using ObjectInputStream.
You cannot do that. If you are going to use ObjectInputStream then you need the other connecting program to write using a ObjectOutputStream.
You telnet client don't really give a shit about the Java ObjectOutputStream, ObjectInputStream and Serialization.
So I'd try something like a InputStreamReader wrapped in a BufferedReader.
If you just want to test the connectivity just write a small java program that will connect to your program instead of using telnet.
David as I mentioned in the comments you have to write a client which uses ObjectOutputStream to send the same DataObject to the server socket.
Since you are expecting DataObject a client needs to send the DataObject. When you use telnet it connects but from there you cannot send the DataObject in a way java Object stream understands.
Please see http://zerioh.tripod.com/ressources/sockets.html for server/client example.
Also since its some school exercise try to understand the concept and do not just copy.
Related
I'm programming in Java and i'm making a socket connection between server and several clients (using threads).
In the client side i made an opened Socket that connects to the server in a respective port and i send several objects, then the client disconnects.
In the server side i made a ServerSocket (where the client connects) and i use the accept() method to get the Socket, i don't want the socket to close so i keep it opened until i want (using a method for example), then i create an stream (ObjectInputStream) and read every object sent from the client, but i don't want it to close too. To continue the understanding of my problem here is the class i made:
import java.io.*;
import java.net.*;
public class ServerConnection implements Runnable{
private Socket connection;
public ServerConnection(Socket c){
connection = c;
}
#Override
public void run() {
// I used String i this example, but the real code use a Object sending system that i created
// because i needed to send different objects in one object (this ones implements Serializable).
String msg;
try {
ObjectInputStream inStream = new ObjectInputStream(connection.getInputStream());
do{
inStream.
msg = ((String)inStream.readObject());
System.out.println(msg);
}
while(!msg.equals("FINISH CONNECTION"));
} catch (IOException ex) {
System.err.println("run() - (io): "+ex.getMessage());
try {
connection.close();
} catch (IOException ex1) {
System.err.println("run() - (io/io): "+ex.getMessage());
}
} catch (ClassNotFoundException ex) {
System.err.println("run() - (classNF): "+ex.getMessage());
}
}
// The main method was created to make tests
// I'll use objects of this class to every client connection
public static void main(String[] args){
try {
ServerSocket server = new ServerSocket(8010);
Socket connection = server.accept();
ServerConnection svConnection = new ServerConnection(connection);
Thread theThread = new Thread(svConnection);
theThread .start();
} catch (IOException ex) {
System.err.println(ex.getMessage());
}
}
}
This can receive the Strings i sent from the client, but the do-while isn't able to catch exceptions, the IOException is throwed when the Stream has no more Strings, so i want to prevent the throwing of that exception when the stream doesn't have more Strings to read, i tried to use recursive try-catch but i know that is not recommended. So there is another solution to this?
(Every answer is welcome. Thanks)
(EDIT)
For those one who needs the client code, so here it is:
import java.io.*;
import java.net.*;
public class ClientConnnection{
// There is a method that i don't make yet
public static void main(String[] args){
try {
Socket socketToServer = new Socket("localhost",8010);
ObjectOutputStream outStream = new ObjectOutputStream(socketToServer.getOutputStream());
outStream.writeObject(new Message("Hello :D"));
outStream.writeObject(new Message("How r u?"));
outStream.writeObject(new Message("Other message"));
outStream.flush();
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
}
}
I am not an expert in networking. However, I started a big project in Java, I already made the SQL database and most of the server, I am only working with TCP at the moment, and I was using Strings as operation identifiers server-side, I don't know if this is correct but is working. Problem is there are operations that require me to send data during all the time while client is connected (like the chat I tried to implement in the last "if" sentence) and I donĀ“t know how to implement it client-side without catching wrong information from other operations like bet results or other things. Should I just use a different port?
public static class Users extends Thread{
private final Socket socket;
private final Connection connection;
private final DataInputStream dataInputStream;
private final DataOutputStream dataOutputStream;
public Users(Socket socket, Connection connection) throws IOException {
this.socket=socket;
this.connection=connection;
this.dataInputStream=new DataInputStream(socket.getInputStream());
this.dataOutputStream=new DataOutputStream(socket.getOutputStream());
}
#Override
public void run(){
while (true){
try {
String operation= dataInputStream.readUTF();
if(operation.equals("Login")){
//censored//
}
if(operation.equals("Register")){
//censored//
}
if(operation.equals("GetClientData")){
//censored//
}
if(operation.equals("Deposit")){
//censored//
}
if(operation.equals("Withdraw")){
//censored//
}
if(operation.equals("PlaceBetOnRoulette")){
//censored//
}
if(operation.equals("PlaceBetOnCrash")){
//censored//
}
if(operation.equals("PlaceBetOnCoinFlip")){
//censored//
}
if(operation.equals("PlaceBetOnSlot")){
//censored//
}
if (operation.equals("SendMessage")){
String message= new String();
message= dataInputStream.readUTF();
if (!message.equals("") && !message.isEmpty()){
for (int i=0;i<arrayList.size();i++){
Socket chatVolatileSocket = (Socket) arrayList.get(i);
DataOutputStream volatileMessageSender= new DataOutputStream(chatVolatileSocket.getOutputStream());
volatileMessageSender.writeUTF(message);
}
}
};
}
catch (IOException e) {
e.printStackTrace();
break;
}
}
try {
arrayList.remove(socket);
socket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
I recommend establishing a more formal message protocol. On a project I am working on I am sending JSON with several common fields like "type" and "time" over web sockets. This can be done similarly using XML if you prefer. This way you can structure your messages.
Also, I meant add this in the comments, but I might as well include this here: Don't use Data streams. Just use plain old Input/OutputStreams. Data streams are Java-only and will lock you into choices that down the road you may very well regret.
My goal is to create a server which receives a Message object from ObjectInputStream, and then echos that Message object to ObjectOutputStream.
Upon writing a message, the client sends the Message type object to the server, the received Message type object (as well as the Message type object from other clients connected to the server) is then received and decoded to the client's gui.
The Message object has a String, and other font information.
My problem is that the server does not echo back the Message type object. I have a feeling that I am not casting properly, but at this point I'm just fishing with trying different things.
The idea is to make the server transparent from the client - is this possible, ie: server does not know anything about the TestObject class? Is there a way around this?
Server code:
import java.net.*;
import java.io.*;
public class Server
{
public SimpleServer() throws IOException, ClassNotFoundException
{
ServerSocket ss = new ServerSocket(4000);
Socket s = ss.accept();
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
// the 'echo' functionality of the server
Object to = null;
try
{
to = ois.readObject();
}
catch (ClassNotFoundException e)
{
System.out.println("broke");
e.printStackTrace();
}
oos.writeObject(to);
oos.flush();
// close the connections
ois.close();
oos.close();
s.close();
ss.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException {
new SimpleServer();
}
}
Client code:
import java.net.*;
import java.io.*;
public class Client
{
public SimpleClient() throws IOException, ClassNotFoundException
{
Socket s = new Socket( "localhost", 4000 );
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream( s.getInputStream());
TestObject to = new TestObject( 1, "object from client" );
// print object contents
System.out.println( to );
oos.writeObject(to);
oos.flush();
Object received = ois.readObject();
// should match original object contents
System.out.println(received);
oos.close();
ois.close();
}
public static void main(String args[]) throws IOException, ClassNotFoundException
{
new SimpleClient();
}
}
class TestObject implements Serializable
{
int value ;
String id;
public TestObject( int v, String s )
{
this.value=v;
this.id=s;
}
#Override
public String toString()
{
return "value=" + value +
", id='" + id;
}
}
Thank you for your time!
EDIT:
This is the output created:
I get this message when the client connects to the server:
Exception in thread "main" java.lang.ClassNotFoundException: TestObject
And this is the client output when I run the client:
value=1, id='object from client Exception in thread "main" java.net.SocketException: Connection reset
First thing : TestObject class is not visible in your Server code. That's why it is throwing ClassNotFoundException.
Solution to this : Put your TestObject class in seperate file and then use import statement to import that class.
Second: Try to print the value of received object at server side. And made changes to your client code as below
Object received = null;
while(received==null)
{
received = ois.readObject();
}
System.out.println(received);
I don't see any problem with your code except you need to flush the oos stream after you write to it in both the server and the client.
oos.flush();
Also for making the server transparent of the client, you can avoid casting on server(which is you are already doing) and the end point should worry about the TestObject which is your client.
Hello I am trying to send an object to a server, and then after the server has received it, taking that same object from the server and reading it as a String in the client output. My initial sent message seems to work while everything after that isnt, here is my code:
import java.io.*;
import java.net.*;
public class GUGLi {
static Socket socket = null;
static ObjectOutputStream out = null;
static ObjectInputStream in = null;
String host = "host";
public static void main(String[] args) throws IOException {
try {
OpenPort();
InfoSent();
ReadInfo();
String line;
while ((line = in.toString()) != null) {
System.out.println(line);
}
} catch (UnknownHostException e) {
System.err.println("Don't know about host: " + "host");
System.exit(1);
} catch (IOException e) {
System.err.println("Couldn't get I/O for "
+ "the connection to: " + "host");
System.exit(1);
in.close();
socket.close();
out.close();
}
}
public static void OpenPort() throws UnknownHostException, IOException{
socket = new Socket ("host", 7879);
}
public static void InfoSent()throws IOException {
Student info = new Student (22, "Guglielmo", "Male",
"email", "#");
out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(info);
System.out.println("Sent: " + info);
out.flush();
}
public static void ReadInfo()throws IOException {
in = new ObjectInputStream(socket.getInputStream());
}
}
line = in.toString() doesn't read lines. It turns an InputStream into its string representation. You need to invoke a read method. If you are hoping to read lines you need BufferedInputStream.readLine(). But if you're reading objects over the same socket you can't mix stream/reader types, so you should read with readUTF() and write with writeUTF() at the other end.
The first problem you have is you're not calling a reading method as sais by #EJP, so see his answer to have more details.
EDIT: I've deleted the information about not being able to receive data in your InputStream. I was wrong about thinking that your socket was not connected to another client, cause i was thinking that String host = "host" would connect to the loopback address, and I was not seeing any code to send data back to your InputStream.
I suggest that you read some tutorials to clear that out. I suggest you Java tutorial about socket to have a strong basic. It will explain everything you need.
I have a chat program. Now the code works for communicate between client and server via command line. But it gives an exception (java.net.SocketException: Socket is closed) while running. Please help me to fix that problem.
In a java chat program,how will the communication be implemented between client and server?
ie.
client<-->server (between server and client)
or
client A<-->server<-->client B (server act as a bridge between two clients)
Is the 2 way communication can be implemented through a single socket?
Are there any other methods ?
How to communicate more than one client simultaneously?
server code
class Server
{
ServerSocket server;
Socket client;
public Server()
{
try
{
server = new ServerSocket(2000);
System.out.println("\tServer Started..........");
while (true)
{
client = server.accept();
Send objsend = new Send(client);
Recive objrecive = new Recive(client);
//client.close();
}
}
catch (Exception e)
{
System.out.println("Exception4 " + e);
}
}
public static void main(String arg[])
{
new Server();
}
}
class Recive implements Runnable
{
Socket client;
public Recive(Socket client1)
{
client=client1;
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
ObjectInputStream ois;
Message M=new Message();
try
{
ois = new ObjectInputStream(client.getInputStream());
M = (Message)ois.readObject();
M.display();
ois.close();
}
catch (Exception e)
{
System.out.println("Exception1 " + e);
}
}
}
class Send implements Runnable
{
Socket client;
public Send(Socket client1)
{
client=client1;
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
try
{
System.out.println("Me(server)");
M.strmessage=br.readLine();
ObjectOutputStream oos=new ObjectOutputStream(cli ent.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
catch (Exception e)
{
System.out.println("Exception " + e);
}
}
}
client code
class Client
{
public static void main(String arg[])
{
try
{
Send objsend=new Send();
Recive objrecive=new Recive();
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Send implements Runnable
{
public Send()
{
Thread trsend=new Thread(this);
trsend.start();
}
public void run()
{
try
{
Message M=new Message();
InputStreamReader isr=new InputStreamReader(System.in);
BufferedReader br=new BufferedReader(isr);
while(true)
{
System.out.println("Me(client)");
M.strmessage=br.readLine();
Socket client=new Socket("localhost",2000);
ObjectOutputStream oos=new ObjectOutputStream(client.getOutputStream());
oos.writeObject((Message)M);
oos.flush();
oos.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
class Recive implements Runnable
{
public Recive()
{
Thread trrecive=new Thread(this);
trrecive.start();
}
public void run()
{
try
{
while(true)
{
Socket client=new Socket("localhost",2000);
ObjectInputStream ois=new ObjectInputStream(client.getInputStream());
Message CNE=(Message)ois.readObject();
CNE.display();
ois.close();
}
}
catch(Exception e)
{
System.out.println("Exception "+e);
}
}
}
First of all, don't close the streams in every run().
Secondly, check whether port for server which you are using is free.
This program makes your pc both host and server.
import java.io.IOException;
import java.net.*;
public class ClientServer {
static byte[] buffer = new byte[100];
private static void runClient() throws IOException {
byte buffer[] = new byte[100];
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds=new DatagramSocket();
int pos = 0;
while (pos<buffer.length) {
int c = System.in.read();
buffer[pos++]=(byte)c;
if ((char)c =='\n')
break;
}
System.out.println("Sending " + pos + " bytes");
ds.send(new DatagramPacket(buffer, pos, address, 3000));
}
private static void runServer() throws IOException {
InetAddress address = InetAddress.getLocalHost();
DatagramSocket ds = new DatagramSocket(3000, address);
DatagramPacket dp = new DatagramPacket(buffer, buffer.length);
ds.receive(dp);
String s=new String(dp.getData(),0,dp.getLength());
System.out.print(s);
}
public static void main(String args[]) throws IOException {
if (args.length == 1) {
runClient();
} else {
runServer();
}
}
}
also follow this link
There could be multiple places where the exception could be thrown. Without a stack trace it is difficult to state so accurately, as to the cause of failure.
But the root cause, is essentially due to the fact that you are closing the InputStream of the socket in your Receiver threads after reading a message, and closing the OutputStream of the socket in your Sender threads after sending a message. Closing either of these streams will automatically close the socket, so you if attempt to perform any further operation on it, a SocketException will be thrown.
If you need to ensure that your server and client do not shutdown in such an abrupt manner, you'll have to keep reading the InputStream (until you get a special message to shutdown, for instance). At the same time, you'll also have to keep writing to the OutputStream. Two-way communication is definitely possible, and the posted code is capable of the same (if the socket remains open).
If you have to handle multiple clients, you'll need multiple reader and writer threads on the server, each listening on an instance of a Socket returned from ServerSocket.accept(); in simpler words, you need a reader-writer pair listening on a distinct socket on the server for each client. At the moment, multiple clients can connect to the Server, as each incoming connection is provided its own client Socket object on the Server, that is provided to individual reader and writer threads. The main Server thread can continue to receive incoming connections and delegate the actual work to the reader-writer pairs.
chat programms normaly have a server through which all communication goes. The reason is that other wise every client needs to know how to reach every other client. And that doesn't work in the general case.
So you'll have a server, every client registers and talks with the server, which will forward messages to other clients.
Mostly communication is done via HTTP cause this is likely to go through firewalls and proxies. You probably want to read up on long polling if you are planning for anything serious.