2017-02-16 222 views
-3

我是Java编程新手,正在尝试开发多客户端聊天服务器。Java多客户端聊天服务器

下面是我的代码:

package Server; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStreamReader; 
import java.net.DatagramPacket; 
import java.net.DatagramSocket; 
import java.net.ServerSocket; 
import java.net.Socket; 
import java.net.SocketException; 
import java.util.ArrayList; 
import java.util.List; 

public class server implements Runnable{ 

    private List<ServerClient> clients = new ArrayList<ServerClient>(); 

//private String UID; 
private int port; 
private ServerSocket socket; 
private Thread run, manage, send, receive; 
private boolean running = false; 
public int i=0; 

    public server(int port){ 
//  this.UID = UID; 
     this.port = port; 
     try { 
      socket = new ServerSocket(port); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     run = new Thread(this, "Server"); 
     run.start(); 
    } 

    @Override 
    public void run() { 
     // TODO Auto-generated method stub 
     running = true; 
     ManageClients(); 
     receive(); 
    } 
    private void ManageClients(){ 
     manage = new Thread("Manage"){ 
      public void run(){ 
       while(running){ 
        //managing 
       } 
      } 
     }; 
     manage.start(); 
    } 

    private void receive(){ 
     receive = new Thread("Receive"){ 
      public void run(){ 
       Socket S1 = null; 
       try { 
        S1 = socket.accept(); 
       } catch (IOException e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 
       while(running){ 

/*     byte [] data = new byte[1024]; 
        DatagramPacket packet = new DatagramPacket(data, data.length); 
        try { 
         socket.receive(packet); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
        String string = new String(packet.getData()); 
        System.out.println(string);*/ 
/*     BufferedReader br = null; 
        try { 
         br = new BufferedReader(new InputStreamReader(S1.getInputStream())); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        } 
        try { 
         String string = br.readLine(); 
         System.out.println(string); 
         process(string); 
        } catch (IOException e) { 
         // TODO Auto-generated catch block 
         e.printStackTrace(); 
        }*/ 
        process(S1); 
        System.out.println(String.valueOf(i)); 
        i++; 
       } 
      } 
     }; 
     receive.start(); 
    } 
    private void process(Socket S1){ 
     BufferedReader br = null; 
     String string = ""; 
     try { 
      br = new BufferedReader(new InputStreamReader(S1.getInputStream())); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     try { 
      string = br.readLine(); 
      System.out.println(string); 
     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     if(string.startsWith("/c/")){ 
      clients.add(new ServerClient("name", S1.getInetAddress(), S1.getPort(), "UID")); 
     } 
     else if(string.startsWith("/ip/")){ 
      //send ip address to raspberry 
      System.out.println(string); 
     } 
     else if(string.startsWith("/r/")){ 
      //send relay command to relay 
      System.out.println(string); 
     } 
    } 
} 

服务器只接受一个连接。如果我尝试连接另一个用户,则控制台不显示任何输出。

你能指导我哪里出错了。

谢谢

+0

这是一个非常宽泛的问题,缺乏具体细节。 – tnw

回答

0

您需要的accept方法多次运行......一旦对于想要连接的每个客户端。由于accept方法阻塞,通常人们在while循环中的单独线程上执行此操作。

在你的代码中,好像你只需要调用accept一次,因此你只会得到一个客户端连接。

我建议你在这里改变你的代码架构,但是如果你想保持它一样,并且你知道有多少客户端将连接,那么你可以将你对socket的访问包装在一个同步锁中,然后打电话给你为每个客户端提供一次receive方法。