2009-09-23 2 views
3

Так что я работал над игрой Tic-Tac-Toe 2 игрока в java, которая использует сокеты. Весь материал сокета работает, и я успешно отправляю данные между двумя клиентами и сервером.Вопрос с отправкой объекта через java-сокеты

У меня есть следующие классы: Requester, Provider и TBoard (который расширяет Serializable).

В классе Requester (клиент) я создаю объект TBoard (TBoard board = new TBoard()).

Затем я отправляю этот объект через сокет моим двум клиентам через выходной поток.

Ошибка я получаю на стороне клиента, и это: Exception in thread "main" java.lang.ClassCastException: java.lang.String

Что происходит с:

board = (TBoard) in.readObject(); in: 

do { 
    try { 
     board = (TBoard) in.readObject(); 
     System.out.println(board.print_board()); 
    } catch (ClassNotFoundException classNot) { 
     System.err.println("data received in unknown format"); 
    } 

Мой метод print_board() в классе TBoard предназначается, чтобы возвращать 2d, но прямо сейчас (упрощение), у меня есть метод, возвращающий строку «Привет» ...

Кто-нибудь знает, почему это может произойти? Я не хотел бомбардировать вас всем кодом, но, пожалуйста, дайте мне знать, если вам будет полезно больше сообщений ...

Спасибо!


UPDATE:

Вот что я собираюсь на (более подробно) с моим провайдером (сервер) Класс:

// 1. creating a server socket 
providerSocket = new ServerSocket(20092); 

// 2. Wait for connection 
System.out.println("Waiting for connection..."); 

connection1 = providerSocket.accept(); 
System.out.println("Connection received from Player 1 " + 

connection1.getInetAddress().getHostName()); 
connection2 = providerSocket.accept(); 
System.out.println("Connection received from Player 2 " + connection2.getInetAddress().getHostName()); 

// 3. get Input and Output streams 
out = new ObjectOutputStream(connection1.getOutputStream()); 

out2 = new ObjectOutputStream(connection2.getOutputStream()); 

in = new ObjectInputStream(connection1.getInputStream()); 
out.writeObject("Player 1 has been connected successfully."); 
in2 = new ObjectInputStream(connection2.getInputStream()); 
out2.writeObject("Player 2 has been connected successfully."); 

out.flush(); 
out2.flush(); 

out.writeObject(board); 
out2.writeObject(board); 

Так что я действительно посылает строку в потоках перед отправкой последнего объекта (платы). Тем не менее, я промываю потоки заранее. Я также попытался выполнить сброс() после флешей, и он все еще дал мне IllegalCastException ...

+0

добавить еще один catch для ClassCastException. Подобно catch (ClassCastException CCE) {CCE.printStackTrace(); } и покажем нам первую строку результата. Я хочу точно знать, в чем причина проблемы. – NawaMan

+0

Он так говорит в вопросе. Я тоже забыл об этом –

ответ

3

IIRC, класс, упомянутый в Exception, был тем, который был фактически найден, поэтому в коде, который вы показываете , ошибка должна быть здесь:

board = (TBoard) in.readObject(); 

И строковый объект вместо TBoard читается из потока.

Edit: Так вы являются отправки строк в дополнение к данным. Там твоя проблема. Вам необходимо либо прекратить отправку этих строк, либо прочитать их на принимающей стороне перед чтением данных. Вызов flush() не имеет к этому никакого отношения - он просто гарантирует, что строки, которые вы уже записали в поток, фактически отправляются по соединению и не сохраняются в буфере.

+0

Что хорошо соответствует окончательным деталям сообщения OPs – spender

+0

На сервере я отправляю объект TBoard с помощью: TBoard board = new TBoard(); out = new ObjectOutputStream (connection1.getOutputStream()); . . . out.writeObject (доска); Так что я не понимаю, почему это читается как String ... – littleK

+1

Очевидно, что вы пишете String и в потоке, где-то перед этой частью. –

2

Чтобы исследовать, я думаю, что самым легким было бы визуализировать (регистрировать или отлаживать) фактический класс, который возникает из in.readObject(). Образец кода:

Object o = in.readObject(); 
    System.out.println("Object of class " + o.getClass().getName() + " is " + o); 
+0

KLE- Отличное предложение. Я попробовал это и получил: «Объект класса java.lang.String - Player 1» на первом клиенте, а «Объект класса java.lang.String - Player 2» на втором клиенте ... Так не должно быть java.lang.String? – littleK

1

Есть несколько возможностей. Предполагая, что вы используете ObjectOutputStream (который, как я думаю, вы есть), возможно, что ошибка возникает из-за того, что вы не полностью сериализуете каждый объект. ObjectOutputStream будет пытаться провести повторную передачу, если вы не будете каждый раз перезагружать поток.

Я хотел бы попробовать следующее:

1) Убедитесь, что вы Flush() и Close() сокеты в соответствующие моменты времени

2) попробуйте вызвать сброс() после того, как каждый объект отправляются.

3) проверьте, что вы отправляете и получаете тот же тип объекта, на всякий случай.

удачи.

+0

UberAlex- См. Мое обновление выше. Как выглядят флеши? – littleK

+0

Я думаю, что флеш обратный. Он должен прийти после записи. – UberAlex