2016-01-13 146 views
1

我刚开始使用Sockets,对于我当前的项目,我需要能够从客户端控制我的程序,但是如果我的项目合作伙伴想同时使用他的客户端,服务器不会向连接类中显示的“您已连接”消息发送给他。所以我假设服务器不能同时接受多个客户端。我曾尝试使用类Connection的线程,但是也不会将消息“您已连接”发送给第二个客户端。我在这里做错了什么?在服务器上接受客户端的多个连接

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

public class Listener extends Thread{ 

private ServerSocket server; 
private int PORT; 
public boolean running; 

public Listener(int port){ 
    try{ 
     this.PORT = port; 
     this.server = new ServerSocket(PORT,10); 
    }catch (IOException e) { 
     System.out.println("Could not create serverSocket..."); 
    } 
} 

@Override 
public void run() { 
    this.running = true; 
    try{ 
     waitForConnection(); 
    }catch(IOException e){ 
     System.out.println("Could not accept connection request.."); 
     run(); 
    } 


} 
public void dispose(){ 
    try{ 
     System.out.println("DISPOSE"); 
     running = false; 
     server.close(); 
    } catch (IOException i) { 
     System.out.println("Could not close ServerSocket"); 
    } 
} 
private void waitForConnection() throws IOException{ 
    while(running){ 
     System.out.println("Waiting for connection"); 
     Socket client = server.accept(); 
     Runnable connection = new Connection(client); 
     new Thread(connection).start(); 
    } 
}  
} 

这是我使用的是有多个用户同时连接螺纹:

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

public class Connection extends Thread { 
    Socket connection; 
    private ObjectOutputStream output; 
    private ObjectInputStream input; 
    private boolean running; 

    public Connection(Socket connect){ 
      this.connection = connect; 
      try { 
       setupStreams(); 
       whileListening(); 
      } catch (IOException e) { 
       System.out.println("could not connect to: "+ connection.getInetAddress().getHostName()); 
    } 
} 

public void dispose(){ 
    try{ 
     output.close(); 
     input.close(); 
     connection.close(); 
     running = false; 
    }catch(IOException ioException){ 
     ioException.printStackTrace(); 
    } 
} 

private void whileListening(){ 
    String message = "You are connected! "; 
    sendMessage(message); 
    do{ 
     try{ 
      message = (String) input.readObject(); 
      checkMessage(message); 
     }catch(ClassNotFoundException classNotFoundException){ 
      sendMessage("tf did you send? "); 
     }catch (IOException e) { 
      dispose(); 
      run(); 
     } 
    }while(!message.equals("Client - END") && running == true); 
} 

private void setupStreams() throws IOException{ 
    output = new ObjectOutputStream(connection.getOutputStream()); 
    output.flush(); 
    input = new ObjectInputStream(connection.getInputStream()); 
} 

private void sendMessage(String message){ 
    try { 
     output.writeObject("Server - " + message+"\n"); 
     output.flush(); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

private void checkMessage(String text){ 
     //check the message 
} 
}  

编辑:Addittional信息

之前的第一个客户端连接,服务器控制台说: “等待连接”,然后当第一个客户端连接时,客户端控制台显示“您已连接”,并且当第二个客户端连接时,控制台是黑色的,当我关闭第一个客户端时,第二个客户端控制台显示“连接“和服务器控制台说”等待连接“,然后如果关闭第二个客户端,服务器控制台会再次显示”正在等待连接“。

+0

您需要使用非阻塞IO – redFIVE

+0

'System.out.println(“等待连接”);'你是否在朋友尝试重新连接之前再次看到该文本? – Soulan

+0

@Soulan我在问题中做了一个编辑,我希望能解释发生了什么。 – IDutch

回答

2

在你的public class Connection extends Thread你这样做whileListening()东西构造函数,所以构造函数永远不会结束,你需要重写run()功能,做到这一点有

@Override 
public void run() { 
    while(true) { 
     try { 
      whileListening(); 
     } catch(Exception e) {} 
    } 
} 

像这样,它应该做的伎俩。

+0

非常感谢!我不能相信这是一个小小的错误,无论如何它现在工作得很好 – IDutch

0

我认为你必须先接受,然后你开始线程。

例如,假设这样的事情

  1. 在主类中,你得到的ServerSocketFactory,然后将ServerSocket。
  2. 然后,(无尽)循环里面,你等待由的ServerSocket.accept()返回一个新的Socket
  3. 只有在此之后,你开始你的线程

下面是从SSLServerSocket一个例子,这是几乎相同的逻辑(认为这是一个伪代码)

SSLContext sc = SSLContext.getInstance("TLS"); 
    (...) 
    SSLServerSocketFactory ssf = sc.getServerSocketFactory(); 
    SSLServerSocket s = (SSLServerSocket) ssf.createServerSocket(portNumber); 
    while (listening) { 
     SSLSocket c = (SSLSocket) s.accept(); 
     log.info("Serving"); 
     new SimpleSSLServerSocketThread(c).start(); 
    }