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.
Related
Client
try {
Socket sock = new Socket("localhost", Integer.parseInt(args[0]));
System.out.println(sock.getLocalAddress());
System.out.println(sock.getLocalPort());
ObjectInputStream ois = new ObjectInputStream(sock.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(sock.getOutputStream());
oos.writeInt(55);
ois.readInt();
} catch (Exception e) {e.printStackTrace();}
Server
try {
ServerSocket ss = new ServerSocket(1234);
Socket sock = ss.accept();
System.out.println(sock.getLocalAddress());
System.out.println(sock.getLocalPort());
ObjectInputStream ois = new ObjectInputStream(sock.getInputStream());
ObjectOutputStream oos = new ObjectOutputStream(sock.getOutputStream());
System.out.println(ois.readInt());
oos.close();
} catch (Exception e) {e.printStackTrace();}
I run the server and then the client, in that order.
I pass 1234 as a command-line argument to the client. In other words, I execute threads this way
java server
java client 1234
Doing that prints these to the console
// server
/127.0.0.1
1224
// client
/127.0.0.1
50261
Neither threads move on from this point.
What's going on here?
Java socket port number changes on its own
No it doesn't. You're looking at two different sockets and two different ports. A connection consists of two endpoints. The localPort of the client socket is 50261, which is the outbound port, and the localPort of the accepted socket at the server is 1234, which is the same as the port being listened at.
Have a look at the respective getRemotePort() values. You will see that the client's is 1234 and the server's is 50261, or rather that it agrees with the client's localPort, whatever it is next time you run it.
Neither threads move on from this point. What's going on here?
You need to construct the ObjectOutputStream before the ObjectInputStream, for reasons explained in the Javadoc and in many answers here, such as this one.
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.
I have the code below:
while (true)
{
lengthInput = instr.readByte();
// Other code
}
The thing is that I'm using a client to send information to the socket, but after it finishes I got EOF Exception and it brokes the thread, what I need is to manages this and dont stop the thread, because I need to send more information and be able to read it.
Thanks in advance for your help.
I guess the problem is related to your socket initialization. You probably need to check if your client socket indeed successfully create a socket and bind to a specified port. You may also check your client really send data to the outstream and flush to the server side. I have a small project on Android emulators with socket communication. Both my client and serve extends from Java Thread class. Maybe you can gain some idea seeing my code below.
The client side
try {
socket = new Socket(InetAddress.getByAddress(new byte[]{10, 0, 2, 2}),
Integer.parseInt(remote_port));//note we must keep the addr#10.0.2.2
// write out
out = new ObjectOutputStream(socket.getOutputStream());
out.writeObject(out_msg);
out.flush();
// read in
in = new ObjectInputStream(socket.getInputStream());
socket.setSoTimeout(1000);
in_msg.set_message((Message)in.readObject());
// close all
out.close();
in.close();
socket.close();
return true;
}catch(InterruptedIOException E){}
The server side
while (true) {
try {
// read in message
Socket ClientSocket = serverSocket.accept();
Message out_msg = new Message();
// read in message
ObjectInputStream in = new ObjectInputStream(ClientSocket.getInputStream());
Message in_msg = (Message) in.readObject();
//Log.d(TAG, "recv" + " content:" + in_msg.msg2Str());
message_process(in_msg, out_msg);
// write out message
ObjectOutputStream out = new ObjectOutputStream(ClientSocket.getOutputStream());
out.writeObject(out_msg);
out.flush();
} catch(Exception E){}
}
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.
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!