2012-05-28 4 views
0

질문이 있습니다. 서버가 있습니다.이 서버는 여러 클라이언트가 연결할 수있는 방식으로 다중 스레드입니다. 클라이언트가 서버에 연결되면 작업을 수행하기 위해 스레드로 던져지고, 다른 클라이언트의 경우에도 마찬가지입니다.각 개별 클라이언트에 대한 다중 스레드 서버

기본적으로 클라이언트가하는 일은 화면에 '그래픽'스퀘어를 그려서 화면에서이 사각형을 움직이면 (키보드 이벤트, 화살표 키 사용) x와 y 코드를 서버로 보내 게됩니다. 처음 연결에서 클라이언트에게 주어진 클라이언트 번호에 해당하는 배열에 배치됩니다.

내 문제는 서버에 x와 y 코드를 보내지 않고 얼마나 많은 클라이언트가 연결되어 있고 x와 y 코드를 저장할 서버에 보내고 플레이어가 새로운 이동을하면 배열의 이전 x와 y는 새 x 및 y 코드로 덮어 씁니다. 나는 모든 사람의 화면에 움직일 것입니다 내 클라이언트의 화면에 내 광장을 이동 인 경우 내 문제는 각 클라이언트를 (그 클라이언트를 포함하지 않음) 다른 클라이언트가 화면에 그리는

...

이 이 이 그래서 기본적으로 (그게 전부가 연결

물론 서버에). ID마다 각 클라이언트에 대해 다중 스레드 서버가 있다고 생각했는데, 이는 ID가 연결 당 두 개의 스레드를 가짐을 의미합니다. 하지만 두 스레드에서 동시에 물건을 앞뒤로 보내는 경우 소켓이 혼란스러워집니다. 게다가 나는 클라이언트가 움직일 때뿐만 아니라 클라이언트가 x와 y 코드의 배열을 지속적으로 받길 원합니다. 그래서 누군가 움직이면 모든 사람을 업데이트 할 것입니다. 또한 새로운 x와 y를 추가로 가져 와서 배열을 올바르게 변경하면서 서버가 지속적으로 x 및 y 코드 배열을 클라이언트에 보내길 원합니다.

기본 구조를 게시하고 누군가가 올바른 방향으로 나를 가리킬 수 있다면 다른 서버 소켓을 만들고 클라이언트의 다른 소켓을 수용해야합니까?

연결 당 스레드 수를 늘리는 방법에 대해 혼란스러워합니다. 고맙습니다! :)

클라이언트 측 :

//some methods are taken out 
// All imports imported here 
public class ClientSquares extends JFrame implements Runnable{ 
    //variables here 
    public void run(){ 
     try{ 
      while(true){ 
       //other calls here (just for client) 
       if(online == true && (x != oldX || y != oldY)){ 
        //only sends its X and Y cords when the player makes a move. 
        checkAbility check = new checkAbility(x, y, clientNum, alpha); 
        check.checking(); 
        //the Checking method in checkAbilities class just assigns a client   
        //number to this client, which is stored in a int variable called 
        //clientNum, once its assigned then it can send its x and Y cords 
       } 
       Thread.sleep(3); 
      } 
     }catch(Exception e){ 
     System.err.println("Error in implemented Runnable's method Run"); 
     } 
    } 

//paint method stuff here, paints the the clients square, and everyone else (according 
//to the array received from the server. 

    public static void main(String [] args){ 
     //thread for client started here 
    } 
    public ClientSquares(){ 
    //standard jFrame here, creates standard x and y cords here 

    //This is how im making my connection with the server right now.. further 
    //communication (in getting client number, and x and y cords are done in a 
    //different class) 
    try{ 
     sock = new Socket("localhost",4000); 
     OS = new DataOutputStream(sock.getOutputStream()); 
     IS = new DataInputStream(sock.getInputStream()); 
     OIS = new ObjectInputStream(sock.getInputStream()); 
     roomNum = IS.readInt(); 
     players = new int[roomNum + 1][2]; 
     defaultPlayerArray(); 
     online = true; 
    }catch(Exception e){ 
     System.err.println("Cannot connect to the Server, check and make sure that the" + 
         " correct ip is entered, and also check if port 777 is open" + 
         " you will now enter offline mode."); 
     online = false; 
    } 
    } 
    class AL extends KeyAdapter{ 
     //Key events here 
    } 
} 

서버 사이드 :

//import heres 
public class ServerRunner{ 
    //variables here, and this class is called somewhere else to start the server, 
    //which 
    //has the server socket, and a couple more variables 
    public ServerRunner(Server2 ser){ 
     serv2 = ser; 
     players = new Socket[ServerRunner.roomNum + 1]; 
     xy = new int[roomNum + 1][2]; 
     gui = new GUI(); 
     string = new String[0]; 
    } 
    //start method is called in the class above, which passes it a server2 object 
    //(itself) 
    public void start(){ 
     try{ 
      serv2.dataServ = new ServerSocket(4000); 
      serv2.listening = true; 
      defaultArray(); 
      gui.main(string); //the GUI class just draws the players for the server to 
           //see 
      System.out.println("Listening for Connections..."); 
     }catch(Exception e){ 
      System.err.println("The port number 777 and 778 are not open"); 
     } 
     while(serv2.listening){ 
      try{ 
       //the data class gives the client a client number, and stores the x & y 
       //cord 
       new data(serv2.dataServ.accept()).start(); 
      }catch(Exception e){ 
       System.err.println("Error in Server Runner"); 
      } 
     } 
    } 
    public void defaultArray(){ 
     for(int i = 0; i < xy.length; i++){ 
      xy[i][0] = -1; 
     } 
    } 
} 

이 문제로 저를 도와 주셔서 감사합니다! :)

편집 : 모두에서 내가 사용하는 메신저,하지만 난 혼합 데이터를받지 않고이 일을 가야합니까 방법이 소켓 (스레드), 여러 일을 할 필요가 하나의 소켓은 그냥해야 한 또 다른 serverSocket?

클라이언트는 x와 y 코드를 서버에 보내 배열에 저장하지만 동시에 다른 플레이어의 x 및 y 코드로 구성된 어레이를 수신하여 동시에 화면에 그릴 수 있습니다. 이 부분을 참조하십시오 스레드가 제자리에 있지만 하나의 소켓으로는 불가능하지는 않지만 매우 어렵습니다.

+0

텍스트에 줄 바꿈을 넣으십시오.) –

+3

그는 혼란 스러울뿐만 아니라 우리를 혼란스럽게합니다. – Ixx

+0

@Daniel H : 고객과의 의사 소통에 필요한 메시지는 무엇입니까? 서버? –

답변

0

서버 당 연결 당 스레드가 두 개인 경우. 하나는 클라이언트 업데이트를 수신합니다. 클라이언트 업데이트마다 적절한 처리를 수행하고 결국에는 내부 상태가 변경된 이벤트를 내 보냅니다.

다른 스레드는 '내부 상태 수정'이벤트를 수신하고 수신하면 자동으로 클라이언트에 새 상태를 보냅니다.

이제 여러 개의 이미 터, 단일 이벤트 및 여러 개의 수신자가 있으므로 이벤트 전체를 신중하게 구현해야합니다.

클라이언트는 다시 서버에 메시지를 보내는 스레드와 업데이트 된 상태를 수신하는 스레드 두 개가 있어야합니다. 그들을 동기화하는 것은 쉬워야합니다. 이 작업을 수행하지 않습니다 또한

, ...

IS = new DataInputStream(sock.getInputStream()); 
OIS = new ObjectInputStream(sock.getInputStream()); 

... 상호 교환 및 IS에서 읽기 OIS하는 문제가 발생할 수 있기 때문이다.

+0

당신이 말한 것에 아직도 여전히 혼란 스럽습니다. –

0

또 다른 접근법은 모든 클라이언트를 서버에 등록하는 것입니다. 그런 다음 모든 클라이언트는 자체 서버 포트를 열어야합니다. 클라이언트가 서버에 새 좌표를 보낼 때마다 서버는이 좌표를 보내는 클라이언트 이외의 모든 클라이언트에이 새 좌표를 보내야합니다.

관련 문제