2013-11-15 2 views
1

저는 입찰 응용 프로그램을 작성하고 서버 (및 스레드 핸들러) 및 클라이언트 (및 클라이언트 핸들러)를 가지고 있습니다. 현재 여러 클라이언트가 잘 연결할 수 있지만 연결할 첫 번째 클라이언트는 시작 메시지를 가져오고 첫 번째 클라이언트가 세 번째 상호 작용 (클라이언트와 서버 간)을 수행 한 후에야 목록의 다음 클라이언트가 시작 메시지를받습니다 . 매번 새로운 스레드를 추가하기 때문에 그 원인을 정확히 알 수 없습니다. 동시에 모든 클라이언트에 writeUTF()의 내용을 표시하지 않습니다.여러 개의 클라이언트 스레드가 연결할 수 있습니다. 스레드는 순차적으로 허용됩니다.

내가 뭘 잘못하고 있는지, 그리고 왜 여러 클라이언트가 동시에 경매를 시작할 수 없는지 알고 싶습니다. 여기 내 코드가있다. 클라이언트 스레드 및 클라이언트

import java.net.*; 
import java.io.*; 
import java.util.*; 

public class Client implements Runnable 
{ private Socket socket    = null; 
    private Thread thread    = null; 
    private BufferedReader console = null; 
    private DataOutputStream streamOut = null; 
    private ClientThread client = null; 
    private String chatName; 


    public Client(String serverName, int serverPort, String name) 
    { 
     System.out.println("Establishing connection. Please wait ..."); 

     this.chatName = name; 
     try{ 
     socket = new Socket(serverName, serverPort); 
     System.out.println("Connected: " + socket); 
     start(); 
     } 
     catch(UnknownHostException uhe){ 
      System.out.println("Host unknown: " + uhe.getMessage()); 
     } 
     catch(IOException ioe){ 
      System.out.println("Unexpected exception: " + ioe.getMessage()); 
     } 
    } 

    public void run() 
    { 
     while (thread != null){ 
     try { 
      //String message = chatName + " > " + console.readLine(); 
      String message = console.readLine(); 
      streamOut.writeUTF(message); 
      streamOut.flush(); 
     } 
     catch(IOException ioe) 
     { System.out.println("Sending error: " + ioe.getMessage()); 
      stop(); 
     } 
     } 
    } 

    public void handle(String msg) 
    { if (msg.equals(".bye")) 
     { System.out.println("Good bye. Press RETURN to exit ..."); 
     stop(); 
     } 
     else 
     System.out.println(msg); 
    } 

    public void start() throws IOException 
    { 
     console = new BufferedReader(new InputStreamReader(System.in)); 

     streamOut = new DataOutputStream(socket.getOutputStream()); 
     if (thread == null) 
     { client = new ClientThread(this, socket); 
     thread = new Thread(this); 
     thread.start(); 
     } 
    } 

    public void stop() 
    { 
     try 
     { if (console != null) console.close(); 
     if (streamOut != null) streamOut.close(); 
     if (socket != null) socket.close(); 
     } 
     catch(IOException ioe) 
     { 
      System.out.println("Error closing ..."); 

     } 
     client.close(); 
     thread = null; 
    } 


    public static void main(String args[]) 
    { Client client = null; 
     if (args.length != 3) 
     System.out.println("Usage: java Client host port name"); 
     else 
     client = new Client(args[0], Integer.parseInt(args[1]), args[2]); 
    } 
} 

import java.net.*; 
import java.io.*; 
import java.util.*; 
import java.net.*; 

클라이언트 스레드

public class ClientThread extends Thread 
{ private Socket   socket = null; 
    private Client  client = null; 
    private DataInputStream streamIn = null; 
    private DataOutputStream streamOut = null; 
    private BufferedReader console; 
    private String message, bidMessage; 




    public ClientThread(Client _client, Socket _socket) 
     { client = _client; 
      socket = _socket; 
      open(); 
      start(); 
     } 
     public void open() 
     { try 
      { 
       streamIn = new DataInputStream(socket.getInputStream()); 
       String auction = streamIn.readUTF(); // Commence auction/ 
       System.out.println(auction); 
       String item = streamIn.readUTF(); 
       System.out.println(item); 

       Scanner scanner = new Scanner(System.in); 
       streamOut = new DataOutputStream(socket.getOutputStream()); 
       message = scanner.next(); 
       streamOut.writeUTF(message); 
       streamOut.flush(); 

      String reply = streamIn.readUTF(); 
      System.out.println(reply); 






      bidMessage = scanner.next(); 
      streamOut.writeUTF(bidMessage); 
      streamOut.flush(); 



      } 
      catch(IOException ioe) 
      { 
      System.out.println("Error getting input stream: " + ioe); 
      client.stop(); 
      } 
     } 
     public void close() 
     { try 
      { if (streamIn != null) streamIn.close(); 
      } 
      catch(IOException ioe) 
      { System.out.println("Error closing input stream: " + ioe); 
      } 
     } 

     public void run() 
     { 
      while (true && client!= null){ 
       try { 

        client.handle(streamIn.readUTF()); 
       } 
       catch(IOException ioe) 
       { 
        client = null; 
        System.out.println("Listening error: " + ioe.getMessage()); 

      } 
      } 
     } 
    } 

BidServer

import java.net.*; 
import java.io.*; 

public class BidServer implements Runnable 
{ 

    // Array of clients 
    private BidServerThread clients[] = new BidServerThread[50]; 
    private ServerSocket server = null; 
    private Thread  thread = null; 
    private int clientCount = 0; 

    public BidServer(int port) 
    { 
     try { 

     System.out.println("Binding to port " + port + ", please wait ..."); 
     server = new ServerSocket(port); 
     System.out.println("Server started: " + server.getInetAddress()); 
     start(); 
     } 
     catch(IOException ioe) 
     { 
      System.out.println("Can not bind to port " + port + ": " + ioe.getMessage()); 

     } 
    } 

    public void run() 
    { 
     while (thread != null) 
     { 
     try{ 

      System.out.println("Waiting for a client ..."); 

      addThread(server.accept()); 

      int pause = (int)(Math.random()*3000); 
      Thread.sleep(pause); 

     } 
     catch(IOException ioe){ 
      System.out.println("Server accept error: " + ioe); 
      stop(); 
     } 
     catch (InterruptedException e){ 
      System.out.println(e); 
     } 
     } 
    } 

    public void start() 
    { 
     if (thread == null) { 
      thread = new Thread(this); 
      thread.start(); 
     } 
    } 

    public void stop(){ 
     thread = null; 

    } 

    private int findClient(int ID) 
    { 
     for (int i = 0; i < clientCount; i++) 
     if (clients[i].getID() == ID) 
      return i; 
     return -1; 
    } 

    public synchronized void broadcast(int ID, String input) 
    { 
     if (input.equals(".bye")){ 
      clients[findClient(ID)].send(".bye"); 
      remove(ID); 
     } 
     else 
     for (int i = 0; i < clientCount; i++){ 
      if(clients[i].getID() != ID) 
       clients[i].send(ID + ": " + input); // sends messages to clients 
     } 
     notifyAll(); 
    } 
    public synchronized void remove(int ID) 
    { 
     int pos = findClient(ID); 
     if (pos >= 0){ 
     BidServerThread toTerminate = clients[pos]; 
     System.out.println("Removing client thread " + ID + " at " + pos); 

     if (pos < clientCount-1) 
      for (int i = pos+1; i < clientCount; i++) 
       clients[i-1] = clients[i]; 
     clientCount--; 

     try{ 
      toTerminate.close(); 
     } 
     catch(IOException ioe) 
     { 
      System.out.println("Error closing thread: " + ioe); 
     } 
     toTerminate = null; 
     System.out.println("Client " + pos + " removed"); 
     notifyAll(); 
     } 
    } 

    private void addThread(Socket socket) throws InterruptedException 
    { 
     if (clientCount < clients.length){ 

     System.out.println("Client accepted: " + socket); 
     clients[clientCount] = new BidServerThread(this, socket); 
     try{ 
      clients[clientCount].open(); 
      clients[clientCount].start(); 
      clientCount++; 
     } 
     catch(IOException ioe){ 
      System.out.println("Error opening thread: " + ioe); 
      } 
     } 
     else 
     System.out.println("Client refused: maximum " + clients.length + " reached."); 
    } 


    public static void main(String args[]) { 
     BidServer server = null; 
     if (args.length != 1) 
     System.out.println("Usage: java BidServer port"); 
     else 
     server = new BidServer(Integer.parseInt(args[0])); 
    } 

} 

BidServerThread

import java.net.*; 
import java.awt.List; 
import java.io.*; 
import java.awt.*; 
import java.util.*; 
import java.util.concurrent.BrokenBarrierException; 


public class BidServerThread extends Thread 
{ private BidServer  server = null; 
    private Socket   socket = null; 
    private int    ID  = -1; 
    private DataInputStream streamIn = null; 
    private DataOutputStream streamOut = null; 
    private Thread thread; 
    private String auctionStart, bid,bidMade,clientBid; 
    private String invalidBid; 
    int firstVal; 

    ArrayList<Bid> items = new ArrayList<Bid>(); 
    //items.add(new Bid()); 
    //items 

    //items 
    //items.add(new Bid("Red Bike",0)); 






    public BidServerThread(BidServer _server, Socket _socket) 
    { 
     super(); 
     server = _server; 
     socket = _socket; 
     ID  = socket.getPort(); 



    } 
    public void send(String msg) 
    { 
     try{ 

      streamOut.writeUTF(msg); 
      streamOut.flush(); 
     } 
     catch(IOException ioe) 
     { 
      System.out.println(ID + " ERROR sending: " + ioe.getMessage()); 
      server.remove(ID); 
      thread=null; 
     } 
    } 
    public int getID(){ 
     return ID; 
    } 

    public void run() 
    { 
     System.out.println("Server Thread " + ID + " running."); 
     thread = new Thread(this); 
     while (true){ 
     try{ 
      server.broadcast(ID, streamIn.readUTF()); 

      int pause = (int)(Math.random()*3000); 
      Thread.sleep(pause); 
     } 
     catch (InterruptedException e) 
     { 
      System.out.println(e); 
     } 
     catch(IOException ioe){ 
      System.out.println(ID + " ERROR reading: " + ioe.getMessage()); 
      server.remove(ID); 
      thread = null; 
     } 
     } 
    } 

    public void open() throws IOException, InterruptedException 
    { 
     streamIn = new DataInputStream(new 
         BufferedInputStream(socket.getInputStream())); 

     streamOut = new DataOutputStream(new 
         BufferedOutputStream(socket.getOutputStream())); 
     String msg2 = "Welcome to the auction,do you wish to start?"; 
    streamOut.writeUTF(msg2); 
    streamOut.flush(); 
    String auctionStart; 
    String bid; 
    String firstMessage = streamIn.readUTF().toLowerCase(); 
    CharSequence yes ="yes"; 
    CharSequence no = "no"; 
    if(firstMessage.contains(yes)) 
    { 

     commenceBid(); 


    } 

    else if(firstMessage.contains(no)) 
    { 
     auctionStart ="Unfortunately, you cannot proceed. Closing connection"; 
     System.out.println(auctionStart); 
     streamOut.writeUTF(auctionStart); 
     streamOut.flush(); 
     int pause = (int)(Math.random()*2000); 
     Thread.sleep(pause); 
     socket.close(); 


    } 
    else if(!firstMessage.contains(yes) && !firstMessage.contains(no)) 
    { 
     System.out.println("Client has entered incorrect data"); 
     open(); 
    } 


    } 

    private void commenceBid() throws IOException { 


     items.add(new Bid("Yellow Bike",0)); 
     items.add(new Bid("Red Bike",0)); 
     //items.add(new Bid("Green bike",0)); 


     String auctionStart = "Auction will commence now. First item is:\n" + items.get(0).getName(); 
     String bidCommence = "Make a bid, whole number please."; 
     synchronized (server) { 
       server.broadcast(ID, bidCommence); 
     } 

     System.out.println("item value is" + items.get(0).getValue()); 
     streamOut.writeUTF(auctionStart); 
     streamOut.flush(); 
     streamOut.writeUTF(bidCommence); 
     streamOut.flush(); 

     bidMade(); 


} 
private void bidMade() throws IOException { 

    bidMade = streamIn.readUTF(); 

    if(bidMade.matches(".*\\d.*")) 
    { 
     int bid = Integer.parseInt(bidMade); 

     if(bid <= items.get(0).getValue()) 
     { 
      String lowBid = "Latest bid is too low, please bid higher than the current bid " + items.get(0).getValue(); 
      streamOut.writeUTF(lowBid); 
      streamOut.flush(); 

      commenceBid(); 
     } 
     if (bid > items.get(0).getValue()) { 

      items.get(0).setValue(bid); 
      String bidItem = "value of current bid is: " + items.get(0).getValue(); 
      streamOut.writeUTF(bidItem); 
      streamOut.flush(); 
      System.out.println("Current bid: " + items.get(0).getValue()); 
      String continueBid = "If you want to make another bid, say yes"; 
      streamOut.writeUTF(continueBid); 
      String continueBidReply = streamIn.readUTF(); 
      { 
       if(continueBidReply.contains("yes") || continueBidReply.contains("Yes")) 
       { 
        commenceBid(); 
       } 
       if(continueBidReply.contains("No") || continueBidReply.contains("No")) 
       { 
        socket.close(); 
       } 
      } 
      streamOut.flush(); 

     } 


    } 

    else 
    { 
      invalidBid = "You have made an invalid bid, please choose a number"; 
      streamOut.writeUTF(invalidBid); 
      streamOut.flush(); 


    } 


} 
public void close() throws IOException 
    { 
     if (socket != null) 
     socket.close(); 

     if (streamIn != null) 
     streamIn.close(); 

     if (streamOut != null) 
     streamOut.close(); 
    } 
} 
+0

디버거를 사용하여 추가 클라이언트를 차단하는 것이 무엇인지 확인합니다. 클라이언트 당 하나씩 여러 스레드를 시작한 것 같습니다. –

답변

1

BidServerThread.open()는 이전에 호출된다 스레드는 BidServer.addThread()에서 시작됩니다. 이렇게하면 호출이 반환 될 때까지 BidServer가 차단되고 다른 클라이언트를받지 못합니다.

BidServerThread.open() ("시작 하시겠습니까?", "예"/ "아니오"등) 다양한 동기식 작업이 클라이언트와 상호 작용합니다. 그것은 결국 반복적으로 (반복) 호출하고 을 호출하고 을 호출 할 수 있으며 이는 클라이언트와 상호 작용하면서 commenceBid()으로 다시 발생할 수 있습니다. 이것이 끝나기 전에 3 가지 상호 작용이있는 시나리오를 가질 수 있습니다.

BidServer.addThread() 대신 BidServerThread.open()BidServerThread.run()에서 호출하여 비동기 적으로 스레드에서 실행할 수 있습니다. (Thread.start()Thread.run()입니다.)

관련 문제