2017-05-22 1 views
-1

플레이어가 토템을 클릭하고 화면에서 위치가 바뀌는 게임 (정글 속도)을 만들고 싶습니다. (스윙을 사용 중이므로 중요하지 않습니다) 및 현지화 변경에 대한 정보를 보내야합니다. 모두에게.두 가지 방법으로 Java 소켓 소켓 열기

나는 플레이어의 클릭을 얻는 서버를 만들고 그것을 확인하고 모두에게 업데이트 정보를 보내고 싶다. 이 시나리오에서 클라이언트는 누군가가 토템을 클릭하고 자신의 클릭에 대한 정보를 보낼 준비가되면 서버를 청취합니다. 서버가 모든 사람의 의견을 경청하고 동시에 모든 사람에게 정보를 보낼 준비가되었습니다. 나는 이것을 다음과 같이 구현하려고한다 : 서버는 각 플레이어에 대한 스레드를 생성하고, 클릭을 위해 내부에서 청취하며, 새로운 토템 현지화를 전송하기 위해 중단 될 준비가되어있다. (나는 ExecutorService에서 shutdownNow 메소드를 사용한다. 루프 작업을 중단하고 새 현지화에 대한 정보를 보내려면 클라이언트 측에서 가져옵니다. 클릭 할 때 클라이언트 측과 동일합니다. 스레드가 인터럽트되어 새로운 클릭을 기다리는 대신 클릭을 보냅니다.

문제는 스트림을 만들 수 없다는 것입니다. 여기서 출력 코드는

클라이언트 측 :

2017-05-22T23:04:06.417Connected 
2017-05-22T23:04:06.417Trying to make output 
2017-05-22T23:04:06.417Trying to make input 

서버 측 :

2017-05-22T23:04:03.278Server Thread :Socket created 
2017-05-22T23:04:03.294Server Thread :Waiting for client! 
2017-05-22T23:04:06.385Server Thread :Correct, connected! 
2017-05-22T23:04:12.239Trying to make input 

클라이언트 측 코드 :

package client; 

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.time.LocalDateTime; 
import java.util.logging.Level; 
import java.util.logging.Logger; 


public class ServerConnection implements Runnable { 

    MainWindow frame; 
    Socket toServ; 
    Socket fromServ; 
    ServerSocket myServ; 
    ObjectOutputStream out; 
    ObjectInputStream reader; 
    public int x, y, totemx, totemy; 
    int i = 0; 

    public ServerConnection(MainWindow frame) { 
     try { 
      this.frame = frame; 
      myServ = new ServerSocket(1338); 
      toServ = new Socket("localhost", 1337); 
      fromServ = myServ.accept(); 
      System.out.println(LocalDateTime.now() + "Connected"); 
      try { 
       System.out.println(LocalDateTime.now() + "Trying to make output"); 
       out = new ObjectOutputStream(new BufferedOutputStream(toServ.getOutputStream())); 
      } catch (IOException ex) { 
       Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex); 
      } 
      System.out.println(LocalDateTime.now() + "Trying to make input"); 
      reader = new ObjectInputStream(new BufferedInputStream(fromServ.getInputStream())); 
     } catch (IOException ex) { 
      Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    @Override 
    public void run() { 
     System.out.println(LocalDateTime.now() + "Running"); 

     while (true) { 
      try { 
       int xGot, yGot; 
       System.out.println(LocalDateTime.now() + "Waiting for params"); 
       xGot = (int) reader.readInt(); 
       yGot = (int) reader.readInt(); 
       System.out.println(LocalDateTime.now() + "I got new params"); 
       frame.refresh(xGot, yGot); 
      } catch (IOException ex) { 
       { 
        try { 
         System.out.println(LocalDateTime.now() + "Sending click thread: Sending my click"); 
         out.writeInt(x); 
         out.writeInt(y); 
         System.out.println(LocalDateTime.now() + "Sent"); 
        } catch (IOException ex1) { 
         Logger.getLogger(ServerConnection.class.getName()).log(Level.SEVERE, null, ex1); 
        } 
       } 
      } 
     } 
    } 
} 

서버 측 코드 첫번째 파일 :

0 (서버가 각 플레이어에 대해 생성되는 클래스가 실행 가능한 구현) 12,379,925,

번째 파일은 : 클라이언트 후 클라이언트가 입력 만들고자 (즉, 서버가 입력했음을 의미) 메이트 출력이 같은

package javaapplicationserwer; 

import java.io.BufferedInputStream; 
import java.io.BufferedOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.net.InetAddress; 
import java.net.Socket; 
import java.time.LocalDateTime; 
import java.util.logging.Level; 
import java.util.logging.Logger; 

public class ClientConnection implements Runnable { 

    Socket fromSocket, toSocket; 
    InetAddress IP; 
    Server serv; 
    ObjectOutputStream out; 
    ObjectInputStream reader; 

    public ClientConnection(Socket fromSocket, Socket toSocket, Server serwer) { 
     this.fromSocket = fromSocket; 
     this.toSocket = toSocket; 
     this.serv = serwer; 
     try { 
      System.out.println(LocalDateTime.now() + "Trying to make input"); 
      reader = new ObjectInputStream(new BufferedInputStream(fromSocket.getInputStream())); 
     } catch (IOException ex) { 
      Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex); 
     } 
     System.out.println(LocalDateTime.now() + "Trying to make output"); 
     try { 
      out = new ObjectOutputStream(new BufferedOutputStream(toSocket.getOutputStream())); 
     } catch (IOException ex) { 
      Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex); 
     } 
    } 

    @Override 
    public void run() { 
     while (true) { 
      System.out.println(LocalDateTime.now() + "Starting"); 
      try { 
       int xGot, yGot; 
       while (true) { 
        System.out.println(LocalDateTime.now() + "Waiting for params"); 
        try { 
         xGot = reader.readInt(); 
         yGot = reader.readInt(); 
         System.out.println(LocalDateTime.now() + "Got this"); 
         //serv.wait(); 
         System.out.println(LocalDateTime.now() + "Waited"); 
         serv.updateIt(xGot, yGot); 
         System.out.println(LocalDateTime.now() + "Verified"); 
        } catch (IOException ex) { 
         try { 
          out.writeInt(serv.x); 
          out.writeInt(serv.y); 
         } catch (IOException ex1) { 
          Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex1); 
         } 
         Logger.getLogger(ClientConnection.class.getName()).log(Level.SEVERE, null, ex); 
        } 

       } 
      } finally { 
       System.out.println(LocalDateTime.now() + "I'm not serving for you"); 
      } 
     } 
    } 
} 

는 소리 그러나 서버는 생성자에서 벗어나 출력을 시도하지도 않습니다.

미리 도움을 청하십시오.

+0

쓰기 호출 후에'out.flush()'를 추가 했습니까? 또한, println 디버깅은 무엇을 보여줍니까? – Gray

+1

'스트림을 만들 수 없음'은 문제 설명이 아니며 '생성자에서 이스케이프'도 아닙니다. – EJP

+0

@Gray out.flush() 도움이되었습니다. 감사합니다 –

답변

0

out.flush()이 경우에 도움이 : 여기

은 단순 TCP를 수행하는 코드입니다.

0

소켓은 2 개의 양방향 연결입니다. 클라이언트 연결에는 하나의 소켓 만 있으면됩니다.

package p; 
import java.io.*; 
import java.net.*; 
import java.util.function.*; 
public class Tcp { 
    static class Acceptor extends Thread { 
     Acceptor(ServerSocket serverSocket,Consumer<Socket> consumer) { 
      super("Acceptor"); 
      this.serverSocket=serverSocket; 
      this.consumer=consumer; 
     } 
     @Override public void run() { 
      p("acceptor running on: "+serverSocket); 
      while(true) 
       try { 
        Socket socket=serverSocket.accept(); 
        if(consumer!=null) consumer.accept(socket); 
       } catch(IOException e) { 
        p(getName()+" caught: "+e); 
        break; 
       } 
     } 
     final ServerSocket serverSocket; 
     final Consumer<Socket> consumer; 
    } 
    static class Connection implements Runnable { 
     Connection(Socket socket) throws IOException { 
      this.socket=socket; 
      in=new BufferedReader(new InputStreamReader(socket.getInputStream())); 
      out=new OutputStreamWriter(socket.getOutputStream()); 
     } 
     boolean send(String string) { 
      try { 
       p("sending: "+string+" on: "+socket); 
       out.write(string+'\n'/*System.getProperty("line.separator")*/); 
       out.flush(); 
       return true; 
      } catch(IOException e) { 
       e.printStackTrace(); 
      } 
      return false; 
     } 
     void process(String string) { 
      p("connection on: "+socket+" received: "+string); 
     } 
     @Override public void run() { 
      p("connection on: "+socket+" is runing."); 
      String string=null; 
      try { 
       p("connection on: "+socket+" is trying to read."); 
       while((string=in.readLine())!=null) { 
        process(string); 
       } 
      } catch(IOException e) { 
       e.printStackTrace(); 
      } 
      process(null); 
      p("connection on: "+socket+" is exiting run()"); 
     } 
     final Socket socket; 
     final BufferedReader in; 
     final Writer out; 
    } 
    public static void p(String string) { 
     System.out.println(string); 
    } 
    Tcp(String host,Integer service) throws IOException { 
     ServerSocket serverSocket=new ServerSocket(); 
     SocketAddress socketAddress=new InetSocketAddress(host,service); 
     serverSocket.bind(socketAddress); 
     Consumer<Socket> socketConsumer=(socket)-> { 
      p("accepted from: "+socket); 
      try { 
       final Connection connection=new Connection(socket) { 
        @Override void process(String string) { 
         super.process(string); 
         send(string.toUpperCase()); 
        } 
       }; 
       new Thread(connection,"incoming").start(); 
      } catch(IOException e2) { 
       e2.printStackTrace(); 
      } 
     }; 
     new Acceptor(serverSocket,socketConsumer).start(); 
    } 
    public static void main(String[] args) throws UnknownHostException,IOException,InterruptedException { 
     final String host="localhost"; 
     final Integer service=1237; 
     Tcp tcp=new Tcp(host,service); 
     Socket socket=new Socket(host,service); 
     Connection c1=new Connection(socket); 
     new Thread(c1,"c1").start(); 
     socket=new Socket(host,service); 
     Connection c2=new Connection(socket); 
     Thread.sleep(500); 
     new Thread(c2,"c2").start(); 
     c1.send("foo"); 
     c2.send("bar"); 
    } 
} 
+0

내가 읽었을 때 나는 시간에 입출력 스트림을 가질 수 없습니다. 내가 잘못? 하나의 소켓이있는 버전이 있었지만 여전히 작동하지 않았습니다. –

+0

@ JakubJabłoński * * 어디서 * 읽습니까? 이 쓰레기는 어디에서 읽었습니까? – EJP