Socket connection closed unexpectedly - java

So I'm just testing out some client-server stuff (I was working on it in a larger project but it kept throwing errors, so I decided to make sure I was doing it right. Turns out I wasn't)
which involves ObjectOutput and Input streams. It works perfectly when I run client and server on localhost, but if I run server on my linux server and client on my computer, the connection has reset by the time I reach the line where the object is fetched. Here's the code:
Client:
public static void main(String[] args){
String[] stuff = {"test", "testing", "tester"};
Socket s = null;
ObjectOutputStream oos = null;
try {
s = new Socket("my.server.website", 60232);
oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(stuff);
} catch (UnknownHostException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally{
try {
s.close();
oos.close();
} catch (IOException e) {}
}
}
Server:
public static void main(String[] args){
ServerSocket ss = null;
Socket s = null;
ObjectInputStream ois = null;
try {
ss = new ServerSocket(60232);
s = ss.accept();
System.out.println("Socket Accepted");
ois = new ObjectInputStream(s.getInputStream());
Object object = ois.readObject();
System.out.println("Object received");
if (object instanceof String[]){
String[] components = (String[]) object;
for (String string : components){
System.out.println(string);
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}finally{
try {
ss.close();
s.close();
ois.close();
} catch (IOException e) {}
}
}

In the client, you are closing the underlying socket s before closing your output stream.
Try this:
try {
oos.close();
s.close();
} catch (IOException e) {}
The oos.close() should cause the object output stream to flush all it's data to the socket and then close the object stream. Then you can close the underlying socket.

Related

How to let a server receive more than a single message from clients?

I want to have a Server that is running and receives messages from Clients such as another Java Applications. I am doing this via BufferedReader with an InputStream and as long as i do it a single time it works as expected. The message gets processed by the method and writes the Test Message of the received message on the screen, but if i let it run in a while loop it says -
java.net.SocketException: Connection reset
So once the Server got a message i dont know how to get a second one, or any following one.
My main source code is:
public static void main (String[] args) {
int port = 13337;
BufferedReader msgFromClient = null;
PrintWriter msgToClient = null;
timeDate td = new timeDate(); //Class i did for myself to get time/date
ServerSocket s_socket = null;
try {
s_socket = new ServerSocket(port);
System.out.println("Server startet at "+td.getCurrDate()+" "+td.getCurrTime());
}
catch (IOException ioe) {
System.out.println("Server on Port "+port+" couldnt be created. \nException: "+ioe.getMessage());
}
Socket socket = null;
try {
socket = s_socket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
msgFromClient = utils.createInputStream(socket);
} catch (IOException ioe) {
System.out.println("Creation of an Input Stream failed.\n Exception - "+ioe);
}
try {
msgToClient = utils.createOutputStream(socket);
} catch (IOException ioe) {
System.out.println("Creation of an Output Stream failed.\n Exception - "+ioe);
}
String input = null;
while (true) {
try {
input = msgFromClient.readLine();
} catch (IOException ioe) {
System.out.println(ioe);
}
if(input!=null) {
System.out.println("Jumping out of loop: "+input);
utils.processCode(input);
}
}
The both classes to create the streams look like this:
public static BufferedReader createInputStream (Socket socket) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
return br;
}
public static PrintWriter createOutputStream (Socket socket) throws IOException {
PrintWriter pw = new PrintWriter(socket.getOutputStream(), true);
return pw;
}
The "processCode" class then simply is a switch.
Socket socket = null;
try {
socket = s_socket.accept();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You only accept one Connection an after this you are doing your handling. You need to open an new Thread for every connection
ExecutorService threadLimit = Executors.newFixedThreadPool(10);
while(true) {
Socket s = serverSocket.accept();
treadLimit.submit(new HandleThread(s));
}

AsynchronousServerSocketChannel with graceful shutdown

In my previous Question i asked how to implement a correct Multithreaded server. I got the response to program a "graceful shutdown", and i tried todo so. However, it didn't work. I still have open sockets in TIME_WAIT state on the client side.
Client:
private <T extends Serializable> T sendCommand(final Command<T> command) throws ExecutionException, InterruptedException, IOException, ClassNotFoundException {
T result = null;
try (final AsynchronousSocketChannel channel = AsynchronousSocketChannel.open(channelGroup)) {
channel.setOption(StandardSocketOptions.SO_REUSEADDR, true);
channel.connect(this.mwInfo.getNextMiddleware()).get();
final OutputStream os = Channels.newOutputStream(channel);
final InputStream is = Channels.newInputStream(channel);
final ObjectOutputStream oos = new ObjectOutputStream(os);
oos.writeObject(command);
oos.flush();
channel.shutdownOutput();
final ObjectInputStream ois = new ObjectInputStream(is);
result = (T) ois.readObject();
while(ois.read() != -1){
System.out.println("busy");
}
try{
channel.shutdownInput();
}catch(Exception ex){
ex.printStackTrace();
}
oos.close();
ois.close();
}
return result;
}
Server:
this.asyncSocket.accept(null, new CompletionHandler<AsynchronousSocketChannel, Void>() {
#Override
public void completed(final AsynchronousSocketChannel result, Void attachment) {
asyncSocket.accept(null, this);
exec.submit(new Runnable() {
#Override
public void run() {
Command cmd = null;
ObjectInputStream ois = null;
ObjectOutputStream oos = null;
try {
ois = new ObjectInputStream(Channels.newInputStream(result));
cmd = (Command) ois.readObject();
while(ois.read() != -1){
System.out.println("busy");
}
result.shutdownInput();
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
try{
oos = new ObjectOutputStream(Channels.newOutputStream(result));
oos.writeObject("test"); //do some other work here..
oos.flush();
result.shutdownOutput();
} catch (IOException e) {
e.printStackTrace();
}
try {
oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
try {
result.close();
}catch (IOException ex){
ex.printStackTrace();
}
}
});
}
#Override
public void failed(Throwable exc, Void attachment) {
}
});
Does anybody know why this isn't a graceful shutdown?
It doesn't look well structured, since i was playing with the try-catch blocks..
Thanks in advance!
I still have open sockets in TIME_WAIT state on the client side.
You will always have sockets in TIME_WAIT on one side or the other, and the client side is where you want them, not the server side.
The state expires after 2*MSL, which means two maximum segment lifetimes, which means two times two minutes.
There is no problem here to solve.

ObjectOutputStream in client causes ServerException

I have a client-server application. Right now, I'm trying to test sending messages from the client to the server and then read them from the server. I'm using ObjectInputStream and ObjectOutputStream to transfer message objects between the client and server.
However, when I try to write an object from the client, it results in a SocketException.
Server code:
while (true) {
try {
log.trace("Waiting for connection.");
Socket clientSocket = socket.accept();
log.trace("Socket connected");
/* create thread */
new Thread(new RequestRunner(clientSocket, serverID)).start();
} catch (SocketTimeoutException e) {
log.trace("Socket timed out.");
socket.close();
break;
} catch (IOException e) {
log.error("Cannot accept connection...");
break;
}
}
Server Thread:
public class RequestRunner implements Runnable {
....
public RequestRunner(Socket socket, UUID serverID) {
client = socket;
this.serverID = serverID;
}
/**
* Start the thread for the request
*/
public void run() {
log.trace("Thread started for socket");
try {
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
} catch (IOException e) {
log.error("Cannot intialize streams...");
return;
}
while(client.isConnected()) {
/* initialize streams */
try {
/* read message */
Object obj = in.readObject(); // does not block
MessageFrame msg = (MessageFrame) obj;
processRequest(msg);
} catch (IOException e) {
; // triggers everytime
//log.error("IO error occured while trying to get input/output stream from socket");
} catch (ClassNotFoundException e) {
log.error("Cannot read MessageFrame");
}
}
}
}
Client code:
public void init(int port) throws IOException {
log.trace("intializing to port " + port);
clientID = UUID.randomUUID();
socket = new Socket("0.0.0.0",port);
out = new ObjectOutputStream(socket.getOutputStream());
in = new ObjectInputStream(socket.getInputStream());
}
public void sendEcho() throws Exception {
while(socket.isConnected()) {
try {
log.trace("Sending echo..");
msg = new EchoMessage(clientID);
curMsgID = msg.getMsgID();
out.writeObject(msg); // throws SocketException, socket closed
out.flush();
break;
} catch (SocketException e) {
log.error ("Cannot send echo.. socket closed.");
break;
} catch (IOException e) {
continue;
}
}
}
The statement out.writeObject(msg) causes a ServerSocket exception with Socket closed as the reason. And the server does not register receiving an object from in.readObject().
netstat shows the connection as established, the error occurs when I try to write the object.
What am I doing wrong ?
You should only have one InputStream and one OutputStream.
out = new ObjectOutputStream(client.getOutputStream());
in = new ObjectInputStream(client.getInputStream());
Should be:
out = client.getOutputStream();
in = client.getInputStream()
And you should change it in the client code when getting the streams from the sockets as well.

Sending objects to localhost server using java?

How do I create a .ser file or write objects to a .ser file in a localhost server?
The following code can read .ser file :
public Object deserialize(InputStream is) {
ObjectInputStream in;
Object obj;
try {
in = new ObjectInputStream(is);
obj = in.readObject();
in.close();
return obj;
} catch (IOException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
throw new RuntimeException(ex);
}
}
URL url;
URLConnection urlConn;
DataInputStream dis;
//url = new URL("http://localhost/Person.ser");
urlConn = url.openConnection();
urlConn.setDoInput(true);
urlConn.setUseCaches(false);
Person person = (person) deserialize(urlConn.getInputStream());
Do I need any server side program to receive the object and store in the file?
you can write to .ser file using following way:
try {
FileOutputStream fos = new FileOutputStream("Filename.ser");
ObjectOutputStream out = new ObjectOutputStream(fos);
out.write(obj);
fos.close();
out.close();
} catch (IOException ex) {}
UPDATE
To read the object at server side you need to create ObjectInputStream wrappint the inputStream of socket via which it is interacting with client . It can be done as follows:
try
{
Socket s = serverSocket.accept();
ObjectInputStream oin = new ObjectInputStream(s.getInputStream());
Object obj = oin.readObject();
oin.close();
}catch(Exception ex){}
OK here is the complete example where I am sending an ArrayList to Server.
Client.java
import java.net.*;
import java.io.*;
import java.util.*;
public class Client
{
public static void main(String[] args)
{
Socket s = null;
ObjectOutputStream out = null;
System.out.println("Connecting to Server ...");
try
{
s = new Socket("localhost", 1401);
out = new ObjectOutputStream (s.getOutputStream());
ArrayList<String> list = ArrayList<String> list = new ArrayList<String>();
for (int i = 0; i < 10 ; i++)
{
list.add("String"+i);
}
out.writeObject(list);out.flush();
System.out.println("ArrayList sent to Server");
} catch ( Exception e)
{
e.printStackTrace();
}
finally
{
if (out!= null)
{
try
{
out.close();
}
catch (Exception ex){}
}
if (s != null)
{
try
{
s.close();
}
catch (Exception ex){}
}
}
}
}
Server.java
import java.net.*;
import java.io.*;
import java.util.*;
public class Server
{
public static void main(String[] args)
{
ObjectInputStream oin = null;
ServerSocket server;
Socket socket = null;
try
{
server = new ServerSocket(1401);
socket = server.accept();
System.out.println("Client Connected..Sending ArrayList to Client");
oin = new ObjectInputStream(socket.getInputStream());
ArrayList<String> list = (ArrayList<String>)oin.readObject();
System.out.println("Recieved ArrayList from client "+list);
//Writing to file now
FileOutputStream fos = new FileOutputStream("Filename.ser");
ObjectOutputStream out = new ObjectOutputStream(fos);
out.write(obj);
fos.close();
out.close();
System.out.println("Written to file");
}
catch(Exception e)
{
e.printStackTrace();
}
finally
{
if (oin != null)
{
try
{
oin.close();
}
catch (Exception ex){}
}
if (socket != null)
{
try
{
socket.close();
}
catch (Exception ex){}
}
}
}
}

Java Client/Server Socket Broken Pipe

I'm creating an update client via Sockets and I'm getting a Broken Pipe on the server side. The server accepts a client socket and responds to the same socket with either a message or a large byte array (~180MB). The error does not happen when testing locally (both client and server on the same machine) and it seems that it happens while sending the byte array. I'm not specifying a time out on the client socket and don't know why it is closing before reading the full response. Its my first time working with sockets and any help would be appreciated.
My Client Socket Code:
public static Response makeRequest(Request req) throws IOException {
Response response = null;
Socket echoSocket = null;
ObjectOutputStream out = null;
ObjectInputStream in = null;
echoSocket = new Socket(serverHost, 10008);
out = new ObjectOutputStream(echoSocket.getOutputStream());
in = new ObjectInputStream(
echoSocket.getInputStream());
BufferedReader stdIn = new BufferedReader(
new InputStreamReader(System.in));
out.writeObject(req);
try {
response = (Response)in.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
out.close();
in.close();
stdIn.close();
echoSocket.close();
return response;
}
Response is just a POJO holding the response (string/byte[] and other data)
My Server Code (copied an example of Sun/Oracle site and added my code to it)
public class Server extends Thread {
private Socket clientSocket;
public Server(Socket clientSocket) {
this.clientSocket = clientSocket;
start();
}
public void run()
{
{
System.out.println ("New Communication Thread Started");
try {
ObjectOutputStream out = new ObjectOutputStream(clientSocket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(clientSocket.getInputStream());
Request request = null;
try {
request = (Request)in.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
UpdateDAO dao = new UpdateDAO();
ClientDAO cdao = new ClientDAO();
Update update = null;
Client client = null;
Session s = HibernateUtil.currentSession();
Transaction t = s.beginTransaction();
if (request != null) {
client = cdao.getClient(request.getClientId());
LogItem log = new LogItem();
log.setClient(client);
log.setTimestamp(new Date());
log.setAction(request.getAction());
if (request.getResponse() != null) {
update = dao.getUpdate(request.getResponse().getUpdateId());
}
TaskContext ctx = new TaskContext(request, client, update, log);
System.out.println("Action: " + request.getAction().getDescription());
Task task = TaskFactory.getTask(request.getAction());
System.out.println(task.getClass().getName());
Response response = task.perform(ctx);
out.writeObject(response);
log.setClientTaskDescription(request.getMessage());
log.setUpdate(ctx.getUpdate());
dao.save(ctx.getLog());
if (ctx.getUpdate() != null) {
dao.update(ctx.getUpdate());
}
} else {
out.writeObject(new Response("what"));
}
t.commit();
out.close();
in.close();
clientSocket.close();
}
catch (IOException e)
{
e.printStackTrace();
System.exit(1);
}
}
}
public static void main(String[] args) throws IOException
{
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(10008);
System.out.println ("Connection Socket Created");
try {
while (true)
{
System.out.println ("Waiting for Connection");
new Server (serverSocket.accept());
}
}
catch (IOException e)
{
System.err.println("Accept failed.");
System.exit(1);
}
}
catch (IOException e)
{
System.err.println("Could not listen on port: 10008.");
System.exit(1);
}
finally
{
try {
serverSocket.close();
}
catch (IOException e)
{
System.err.println("Could not close port: 10008.");
System.exit(1);
}
}
}
}
If the client is, in fact, running out of memory:
java -Xmx512m -jar <the jar>
or
java -Xmx512m com.foo.blah.YourClass
would increase the maximum heap for the client/server. Keep in mind you may have to increase the heap for both sides of the pipe since both sides would be reading all ~180mb into memory at runtime.

Categories

Resources