2014-10-11 232 views
0

我想在Java中實現一個多線程的服務器聊天應用程序。
該程序創建了一個線程並等待客戶端進行連接。一旦客戶端連接,它會創建另一個線程並等待另一個客戶端連接。創建多線程Java服務器聊天應用程序。

這是我ChatServer.java

package com.chat.server; 



import java.io.InputStream; 
import java.io.IOException; 
import java.net.Socket; 
import java.net.InetAddress; 
import java.net.ServerSocket; 



/** 
* <p>The chat server program</p> 
* This class is a Thread that recieves connection 
* from different clients and handles them is separate 
* Thread. 
* 
* @author Aditya R.Singh 
* @version 1.0.0 
* @since 1.0.0 
*/ 
class ChatServer extends Thread { 

    private int port;     // The port number to listen at. 
    private String ip;     // To store the IP address. 
    private Socket socket;    // Socket connection with different clients. 
    private InetAddress inet;   // Handling Client Address. 
    private ServerSocket serverSocket; // The server socket used by clients to connect. 



    /** 
    * This is solely intended for instantiation purpose. 
    * 
    * @param PORT - The port number to listen for client requests 
    */ 
    ChatServer(final int PORT) { 


     /* Initiallizing all instance variables to null. */ 
     ip = null; 
     inet = null; 
     socket = null; 
     serverSocket = null; 

     /* Initiallizing the port number. */ 
     port = PORT; 
    } 



    /** 
    * This method creates a connection between server and client. 
    * 
    * @throws java.io.IOException 
    */ 
    private void createConnection() throws IOException { 

     serverSocket = new ServerSocket(port); // Listen to the required port. 
     socket = serverSocket.accept();   // Accept the client connection. 
    } 



    /** 
    * This method sets the IP address. 
    */ 
    private void setIP() { 

     inet = socket.getInetAddress(); 
     ip = new String(inet.getHostAddress()); 
    } 



    /** 
    * This method returns the IP address. 
    * 
    * @return IP address. 
    */ 
    public String getIP() { 

     return ip; 
    } 



    /** 
    * This method checks if the socket has been connected 
    * with any client. 
    * 
    * @return True if the client has been connected, else false 
    */ 
    public boolean isConnected() { 

     if(socket == null) 
      return false; 
     return true; 
    } 



    /** 
    * This method returns the InputStream 
    * from the Socket. 
    * 
    * @return InputStream if Socket has been connected to the client, else null 
    * @see java.io.InputStream 
    */ 
    public InputStream getInputStream() throws IOException { 

     if(socket == null) 
      return null; 
     return socket.getInputStream(); 
    } 



    @Override 
    public void run() { 

     try { 

      createConnection(); 
      setIP(); 
     } catch(IOException exception) { 

      exception.printStackTrace(); 
     } 
    } 
} 

這是我Server.java

package com.chat.server; 



/** 
* <p>The Server app</p> 
* This is the controller for accepting connections. 
* 
* @author Aditya R.Singh 
* @version 1.0.0 
* @since 1.0.0 
*/ 
public class Server { 


    /** 
    * The port at which clients will connect. 
    */ 
    public static final int PORT = 6005;   



    /** 
    * For instantiation purpose. 
    */ 
    public Server() { 


    } 



    public static void main(String[] args) { 


     /* Keep accepting connections. */ 
     while(true) { 

      ChatServer chat = new ChatServer(PORT); // Connecting port. 
      chat.start(); 

      while(!chat.isConnected()) 
       /* This is a false loop. Intended to keep running unless another client is not requesting to connect. */; 

      System.out.println("We connected to: "+chat.getIP()); 
     } 
    } 
} 

代碼編譯的罰款。
在運行代碼:

java com.chat.server.Server 

似乎該程序監聽客戶端連接。但是在連接到客戶端之後,需要打印客戶端的IP地址,然後爲另一個客戶端創建另一個線程。但它不打印客戶端的IP。

這是我Client.java

package com.chat.client; 



import java.net.Socket; 
import java.io.IOException; 



public class Client { 

    public static void main(String[] args) { 

     Socket socket = null; 


     try { 

      socket = new Socket("127.0.0.1", 6005); 
      System.out.println("Socket connected."); 
     } catch(IOException ex) { 

      ex.printStackTrace(); 
     } 
    } 
} 

客戶端的人連接到服務器,必須打印Socket connected。客戶端這樣做。客戶端工作正常:

java com.chat.client.Client 
Socket connected. 

但服務器應用程序不打印客戶端的IP地址。爲什麼這樣?

+0

這[代碼](http://stackoverflow.com/a/25778305/3857942)可能給你如何做一個聊天服務器的想法。 – 2014-10-11 06:07:45

回答

1

這不是完整的代碼

package demo; 

import java.io.IOException; 
import java.net.ServerSocket; 
import java.net.Socket; 



public class MultithreadedServer { 

    public static final int PORT = 10000; 

    public static void main(String[] args) { 
     try(ServerSocket server = new ServerSocket(PORT)) { 
      while(true){ 
       Socket connection = server.accept(); 
       Thread client = new ClientThread(connection); 
       client.start(); 
      } 
     } catch (IOException ex) { 
      System.out.println("Error start server"); 
     } 
    } 

} 

class ClientThread extends Thread { 
    private Socket connection; 

    public ClientThread(Socket connection) { 
     this.connection = connection; 
    } 

    @Override 
    public void run(){ 
     //Do communication with client 
    } 

} 
+0

嘿哇。這件事情奏效。非常感謝 – 2014-10-13 02:50:05

1

這是一種競爭條件。行socket = serverSocket.accept();導致while(!chat.isConnected())循環在調用方法'setIP()'之前終止。一個快速的方法來驗證,這是問題的原因是通過改變這個方法:

public boolean isConnected() { 
    if(socket == null) 
     return false; 
    return true; 
} 

public boolean isConnected() { 
    if(socket == null || ip == null) 
     return false; 
    return true; 
} 

爲了解決這個問題,你應該確保該代碼集IP和檢查其是否連接的代碼使用​​關鍵字。此外,請注意while(!chat.isConnected())循環沒有暫停運行,這意味着它需要儘可能多的CPU,因爲它是可用的...這絕對不是好的。

請查看@Michael Petch發佈的用於正確實現聊天服務器的鏈接。

相關問題