1

클래스가 있습니다. Client, Server 및 Background가 Player 클래스에서 작동합니다. ObjectInputStream/ObjectOutputStream 인 클라이언트 클래스가 올바르게 작동하지 않는 이유를 정말로 이해하지 못합니다.ObjectInputStream/ObjectOutputStream 작업이 올바르지 않습니다.

내가 뭘 잘못하고있어? 내 실수는 어디 갔어?

package Shooter2Dv27082013; 
public class Player implements Serializable{ 
.... 
public int x=10; 
public int y=10; 
.... } 

package Shooter2Dv27082013; 
public class Background extends JPanel implements ActionListener, Serializable { 
public int countCollisions=0; 
private int time = 20;      // 0.02s 
Timer mainTimer = new Timer(time, this); 
.... 
Player p = new Player(); ... } 

이제 클라이언트 클래스 :

package Shooter2Dv27082013; 


import javax.swing.*; 
import java.net.*; 
import java.io.*; 

public class Client { 
    public static void main(String[] ar) { 
     JFrame frame = new JFrame("D2 Shooter"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(1000, 520); 
     Background bg = new Background(); 
     frame.add(bg); 
     frame.setResizable(false); 
     frame.setVisible(true); 

     int serverPort = 6666; 
     String address = "127.0.0.1";/

     Player p = new Player(); 
     try { 
      InetAddress ipAddress = InetAddress.getByName(address); 
      System.out.println("Any of you heard of a socket with IP address " + address + " and port " + serverPort + "?"); 
      Socket socket = new Socket(ipAddress, serverPort); 
      System.out.println("Yes! I just got hold of the program."); 

      InputStream sin = socket.getInputStream(); 
      OutputStream sout = socket.getOutputStream(); 

      ObjectInputStream ois = new ObjectInputStream(sin); 
      ObjectOutputStream oos = new ObjectOutputStream(sout); 

      System.out.println("Streams are created. Let's try send these objects"); 
      System.out.println(); 


      System.out.println("P.x : "+bg.p.x); 
      while (true) { 
       oos.writeObject(bg.p); 
       oos.flush(); 
       oos.close(); 
       System.out.println("Player X: " + bg.p.x + " Player Y: " + bg.p.y); 
       p = (Player) ois.readObject(); 
       ois.close(); 
       System.out.println("New X: " + p.x + "New Y: "+p.y); 
       System.out.println("Looks like the server is pleased with us. Go ahead and enter more lines."); 
       System.out.println(); 
      } 

     } catch (Exception x) { 
      x.printStackTrace(); 
     } 
    } 
} 

이 서버 클래스에 객체를 전송하지 않습니다, 그러나 그것은 또한 오류에 대해 아무것도 말하지 않는다.

서버 클래스 :

package Shooter2Dv27082013; 

import java.net.*; 
import java.io.*; 
public class Server { 
    public static void main(String[] ar) { 
     int port = 6666; 
     try { 
      ServerSocket ss = new ServerSocket(port); 
      System.out.println("Waiting for a client..."); 

      Socket socket = ss.accept(); 
      System.out.println("Got a client :) ... Finally, someone saw me through all the cover!"); 
      System.out.println(); 

      InputStream sin = socket.getInputStream(); 
      OutputStream sout = socket.getOutputStream(); 

      ObjectInputStream ois = new ObjectInputStream(sin); 
      ObjectOutputStream oos = new ObjectOutputStream(sout); 

      Player p = new Player(); 

      while(true) { 
       p = (Player) ois.readObject(); 
       System.out.println("The client just sent me this x: "+p.x+" y: "+p.y); 
       p.x=555; p.y=600; 
       System.out.println("I change it and now I'm sending it back..."); 
       oos.writeObject(p); 
       oos.flush(); 
       oos.close(); 
       System.out.println("Waiting for the next line..."); 
       System.out.println(); 
      } 
     } catch(Exception x) { x.printStackTrace(); } 
    } 
} 

답변

2

당신은 루프에서 스트림을 닫는. 스트림이나 모든 리소스는 닫은 후에 사용할 수 없습니다.

+0

@ Eldar 코드에 문제가있는 것은 확실하지만이 문제 만 해결해도 문제가 해결되지는 않습니다. 게시 된 코드는 "스트림이 생성되었습니다.이 객체를 보내 봅시다"라는 문구를 인쇄하는 것까지까지 미치지 못합니다. – EJP

5

ObjectInputStream보다 먼저 ObjectOutputStream을 생성해야합니다. 현재 교착 상태에 처해 있습니다.

너도 은 루프 외부에서 닫기를 이동해야합니다.

0

좋아요, 이것이 개체 스트림이 작동하는 방식과 모든 곳에서 작동하는 솔루션입니다.

오브젝트 스트림 데이터 앞에는 4 바이트 '마법'시퀀스 AC ED 00 05가옵니다. 은 첫 번째 읽기 전이 아닌 작성시이 데이터를 들여다 봅니다. 논리적입니다. 응용 프로그램에서 너무 멀리 떨어져 있기 전에 적절한 스트림인지 확인하고 싶습니다. 시퀀스는 구성시에 ObjectOutputStream에 의해 버퍼링되므로 첫 번째 쓰기시 스트림에 푸시됩니다. 이 방법은 버퍼링 된 상황이나 파이프 또는 소켓을 통한 전송에서 복잡성을 초래합니다. 다행히도 이러한 모든 문제에 대한 간단한 해결책이 있습니다.

건설 직후에 ObjectOutputStream을 세척하십시오!

ObjectOutputStream myStream = new ObjectOutputStream (anotherStream); 
myStream.flush(); 

귀하의 경우 클라이언트 및 서버 앱 모두에 해당됩니다.

+0

차단 모드에서는 'peek [ed]'가 아니며 * 읽기 *됩니다. 첫 번째 쓰기시 스트림에 푸시되지 않는다. 그 자체는 작성된 것이다. 그 아래에 버퍼링 된 스트림이 있으면 첫 번째 * flush()'*까지 버퍼링된다. 그렇지 않으면 바로 나타난다. – EJP