2015-05-13 3 views
0

У меня есть клиент-серверное приложение. Сейчас я пытаюсь проверить отправку сообщений с клиента на сервер, а затем читать их с сервера. Я использую ObjectInputStream и ObjectOutputStream для передачи объектов сообщений между клиентом и сервером.ObjectOutputStream в клиенте вызывает ServerException

Однако, когда я пытаюсь написать объект от клиента, это приводит к SocketException.

Серверный код:

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; 
     } 
    } 

Сервер Тема:

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"); 
     } 
    } 
} 

}

код клиента:

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; 
     } 
    } 
} 

Оператор out.writeObject(msg) вызывает ServerSocket исключение с Socket closed как причина. И сервер не регистрирует получение объекта с in.readObject().

netstat показывает соединение, как установлено, ошибка возникает, когда я пытаюсь записать объект.

Что я делаю неправильно?

ответ

0

У вас должен быть только один InputStream и один OutputStream.

out = new ObjectOutputStream(client.getOutputStream()); 
in = new ObjectInputStream(client.getInputStream()); 

Должно быть:

out = client.getOutputStream(); 
in = client.getInputStream() 

И вы должны изменить его в коде клиента при получении потоков из розеток, а также.

+0

Я не уверен, что понимаю, что вы предлагаете. Не существует ли только одного объекта ObjectOuputStream и одного объекта ObjectInputStream для каждого клиентского соединения? Это только один раз инициализируется в другом потоке (класс 'RequestRunner'). И как бы двусторонняя связь работала без входных/выходных каналов с обоих концов? –

+1

прямо сейчас вы используете ключевое слово new, и это создает новый экземпляр ObjectInputStream и ObjectOutputStream. Вы можете получить соединение, просто написав client.getOutputStream и т. Д. – Anon

+0

Hm, 'out' имеет тип' ObjectOutputStream' и 'client.getOutputStream()' возвращает 'OutputStream'. Я не могу назначить его, я думал, что лучшим способом было бы превратить «OutputStream» в новый экземпляр «ObjectOutputStream». Этот вопрос [вопрос] (http://stackoverflow.com/questions/8240701/serialize-object-with-outputstream) отвечает на него одинаково. Если не существует статического метода для преобразования 'OutputStream' в' ObjectOutputStream'. –

Смежные вопросы