2014-09-12 6 views
0

저는 다양한 TCP 네트워크 장치와 연결되는 프로그램을 작성하고 있습니다. GUI는 JavaFX를 사용하여 만들어집니다. 전체 연결 부분은 자체 패키지 "네트워크"에 있습니다. 대략 묘사하면 다음과 같이 보입니다 : (나는 UML에 대해 많이 모른다. 비난하는 plaese :/- 나는 단지 내 프로그램 구조가 어떻게 보이는지 빨리 설명하는 방법이 필요했다.)이벤트를 사용하여 네트워크 관리자를 분리 할 수 ​​있습니까?

괜찮 냐구 : TCP 클래스는 "NetworkManager"의 동기화 된 목록에 저장됩니다. 이 클래스는 연결 정보 (얼마나 많은 데이터를 받았는지, ip, mac 등)를 저장합니다. Rcv-Thread는 끊임없이 데이터 수신을 시도합니다.

글쎄, 이것은 내가 원하는 것입니다 : Rcv-Thread가 특정 메시지를 받자 마자 컨트롤러가 어떤 일을하도록 호출되어야합니다 (GUI 새로 고침 등). 또한 컨트롤러는 다른 프로젝트에서 재사용되는 "네트워크"모듈에서 분리 된 상태를 유지해야합니다. 커스텀 이벤트를 통해이 동작을 구현하고 싶습니다. 요약하면 : TCP-Rcv-Thread는 컨트롤러에 정보를 제공 할 수 있어야합니다. 그러나 나는 그걸 모두 작동시키는 법을 정말로 모른다. 내가 어디 있는지 보자 :

  • "Network"모듈에 이벤트 클래스가 있습니다.

    import java.util.EventObject; 
    
    public class XEvent extends EventObject{ 
        String message; 
        public XEvent(Object source, String message) { 
        super(source); 
        this.message = message; 
        } 
    
    public String getMessage() { 
        return message; 
    } 
    } 
    
  • "네트워크"모듈에 리스너 클래스가 있습니다.

    import java.util.EventListener; 
        public interface XListener extends EventListener{ 
        void handlerMethod1(XEvent event); 
        void handlerMethod2(XEvent event); 
    } 
    
  • 내가 이벤트 해고 내 수신음 - 스레드를 준비하려고 :

    public class Controller implements Initializable, XListener { 
    @Override 
    public void handlerMethod1(XEvent event) { 
        System.out.println("Event1: " + event.getMessage()); 
    } 
    
    @Override 
    public void handlerMethod2(XEvent event) { 
    
    } 
    } 
    
  • :

    import javax.swing.event.EventListenerList; 
    import java.io.IOException; 
    
    public class ReceiveDataThread implements Runnable { 
    protected EventListenerList listenerList = new EventListenerList(); 
    } 
    
    protected void addXListener(XListener xListener) { 
         listenerList.add(XListener.class, xListener); 
        } 
    
    
    
    protected void removeListener(XListener xListener) { 
         listenerList.remove(XListener.class, xListener); 
        } 
    
    protected void fireHandlerMethod1(String message) { 
        XEvent event = null; 
        Object[] list = listenerList.getListenerList(); 
        for (int i = 0; i < list.length; i += 2) { 
         if (list[i] == XListener.class) { 
          if (event == null) event = new XEvent(this, message); 
          XListener l = (XListener) list[i + 1]; 
          l.handlerMethod1(event); 
         } 
        } 
    } 
    
    protected void fireHandlerMethod2(String message) { 
        XEvent event = null; 
        Object[] list = listenerList.getListenerList(); 
        for (int i = 0; i < list.length; i += 2) { 
         if (list[i] == XListener.class) { 
          if (event == null) event = new XEvent(this, message); 
          XListener l = (XListener) list[i + 1]; 
          l.handlerMethod2(event); 
         } 
        } 
    } 
    
    @Override 
    public void run() { 
        String s; 
        while (!stopThread) { 
         s = receiveData(); 
         System.out.println("test"); 
         fireHandlerMethod1(s); 
        } 
    } 
    
  • 컨트롤러를 (사용자 정의 이벤트에 반응해야이 클래스)는 리스너를 구현

그리고 거기에서 나는 정말 내 일이 내 Rcv- 스레드) 내 컨트롤러 클래스에 의해 발견됩니다. 컨트롤러 클래스를 통해 모든 Rcv-Thread 객체에 리스너를 추가해야한다고 생각합니다 (ButtonListener를 사용할 때처럼 ...). 문제는 : 내 TCP 클래스에서 public으로 설정되어 있어도 Rcv-Thread-object의 addXListener 메서드 ()에 액세스 할 수 없습니다 (목록에서 Rcv-Thread-Class에 액세스 할 수 있음). 나는 문제에 관해 할 수있는 한 많은 것을 읽으려고했으나 이것을 작동시키는 법을 이해하지 못했다. 나는 무엇을 놓치고 있습니까?

EDIT1 : TCP 클래스 다음 네트워크 매니저는 TCPClass의 객체를 생성하고 연결() 메서드를 호출

public class TCPClass{ 
private Thread receiveDataThread; 
private String MAC;  
private InetAddress IP; 
private Socket socket = new Socket(); 
private int tcpSendPort; 
private int timeOut = 10;  
private ObjectOutputStream objectOutputStream; 
private BufferedReader bufferedReader; 
private String connectionStatus = "offline"; 


public TCPClass(DatagramPacket datagramPacket) { 
    IP = datagramPacket.getAddress(); 
    setConnectionStatusOnline(); 
    tcpSendPort = 50000 + NetworkManager.getNumberOfConnections(); 
    MAC = extractMac(datagramPacket); 
} 
    public void connect(int tcpPort) { 
    try { 
     socket = new Socket(IP, tcpPort, null, tcpSendPort); 
     bufferedReader = new BufferedReader(new InputStreamReader(socket.getInputStream())); 
     receiveDataThread = new Thread(new ReceiveDataThread(this)); 
     receiveDataThread.start(); 
     InputStreamReader(socket.getInputStream())); 
    } catch (IOException e) { 
     e.printStackTrace(); 
     System.out.println("on MAC: " + getMAC() + "\non Device:" + toString()); 
    } 
    if (socket.isConnected()) { 
     setConnectionStatusConnected(); 
    } 
} 
} 

.

+0

당신은 일반적인 자바 직렬화를 사용하고 있습니까? 아니면 실제로 TCP 프로토콜을 구현하고 네트워크를 통해 전송하고 있습니까? –

+0

표준 Java 소켓 -> 소켓 (IP.tcpPort, null, tcpSendPort), 그리고 bufferedReader.read()를 통해 데이터를받습니다. 그래서 내 자신의 TCP 프로토콜을 구축하지 않았습니다. 이것이 의미하는 것이면 – JohnSmith

+0

입니다. 그렇다면 직렬화하는 것입니다 : P 게시 TCP 클래스? (또는 하나의 구현) –

답변

0

오케이 그래서 나는 나 자신을 알아 냈습니다. 주된 문제는 컨트롤러에서 Rcv-Thread의 addXListener() 메서드를 호출 할 수 없다는 것이 었습니다. Rcv-Thread에서 사용자 지정 이벤트 항목을 가져 와서 TCP 클래스로 이동했습니다. 이제 리스너를이 클래스에 추가 할 수 있습니다. Rcv-Thread에서 이벤트를 발생 시키려면 FireHandlerMethod()를 슈퍼 클래스 (TCP 클래스)에서 호출하기 만하면 모든 것이 예상대로 작동합니다.