2014-10-11 273 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发布的用于正确实现聊天服务器的链接。