2013-11-15 79 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(),而後者又可以調用bidMade(),這又可以在同步與客戶端的交互過程中重複出現commenceBid()。在結束之前可以有一個你有3次交互的場景。

我想,你可以爲了調用BidServerThread.open()BidServerThread.run(),而不是在BidServer.addThread()它在其線程異步運行。 (Thread.start()調用Thread.run()。)