发送给所有客户

时间:2013-05-11 15:28:20

标签: java sockets client-server

我需要你的帮助:D 所以,我正在尝试构建一个简单的Java多套接字服务器。我在这里开始使用此代码:http://www.kieser.net/linux/java_server.html并对其进行了一些修改。运作良好,但我需要将消息发送回所有客户,而不仅仅是发送给他们的人。 继承我的修改后的代码:

import java.io.*;
import java.net.*;
import java.util.Date;

public class Main {

    private static int port=4444, maxConnections=0;
    private static Date date = new Date();

    // Listen for incoming connections and handle them
    public static void main(String[] args) {
        int i=0;
        System.out.println("[Notice][" + date.toString() + "] - Server started!");
        try{
            ServerSocket listener = new ServerSocket(port);
            Socket server;

            while((i++ < maxConnections) || (maxConnections == 0)){
                server = listener.accept();
                doComms conn_c= new doComms(server);
                Thread t = new Thread(conn_c);
                System.out.println("[Notice][" + date.toString() + "] - Client connected! ID: " + i);
                t.start();
            }

        } catch (IOException ioe) {
            System.out.println("IOException on socket listen: " + ioe);
            ioe.printStackTrace();
        }
    }

}

class doComms implements Runnable {
    private Socket server;
    private String line;

    private static Date date = new Date();

    doComms(Socket server) {
        this.server=server;
    }

    public void run () {

        try {
            // Get input from the client
            DataInputStream in = new DataInputStream (server.getInputStream());
            PrintStream out = new PrintStream(server.getOutputStream());

            while((line = in.readLine()) != null && !line.equals("exit")) {
                out.println("Somebody says: " + line);
                log("Message: " + line, 0);
            }
            log("Server closed", 0);
            server.close();
        } catch (IOException ioe) {
            System.out.println("IOException on socket listen: " + ioe);
            ioe.printStackTrace();
        }
    }

    void log(String msg, int lvl)
    {
        if(lvl == 0)
        {
            System.out.println("[Notice][" + date.toString() + "] - " + msg);
        }else if(lvl == 1)
        {
            System.out.println("[Warn][" + date.toString() + "] - " + msg);
        }else if(lvl == 2)
        {
            System.out.println("[Error][" + date.toString() + "] - " + msg);
        }
    }
}

我确定它没什么可做的,但我不明白:D 谢谢你的帮助!

//修改

现在这是工作代码,我不确定:我应该使用多播套接字吗?他们有更好的表现吗?

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Date;

public class Main {

    private static int port=4444, maxConnections=0;
    private static Date date = new Date();

    // Listen for incoming connections and handle them
    public static void main(String[] args) {
        int i=0;
        System.out.println("[Notice][" + date.toString() + "] - Server started!");
        try{
            ServerSocket listener = new ServerSocket(port);
            Socket server;

            while((i++ < maxConnections) || (maxConnections == 0)){
                server = listener.accept();
                doComms conn_c= new doComms(server, i -1);
                Thread t = new Thread(conn_c);
                System.out.println("[Notice][" + date.toString() + "] - Client connected! ID: " + i);
                t.start();
            }

        } catch (IOException ioe) {
            System.out.println("[Error][" + date.toString() + "] - " + ioe);
            ioe.printStackTrace();
        }
    }

}

class doComms implements Runnable {
    private Socket server;
    private String line;

    private int client_id;
    private boolean cmd = false;

    private DataInputStream in;
    private PrintStream out;

    private static ArrayList<doComms> clients = new ArrayList<doComms>(); 

    private static Date date = new Date();

    doComms(Socket server, int id) {
        this.server = server;
        this.client_id = id;
        clients.add(this);
    }

    public void run () {

        try {
            // Get input from the client
            in = new DataInputStream (server.getInputStream());
            out = new PrintStream(server.getOutputStream());

            while((line = in.readLine()) != null && !line.equals("shutdown") && !line.equals("exit")) {
                send_toAll(line, this.client_id);
                log("Message: " + line, 0);
            }

            if(line.equals("shutdown"))
            {
                log("Got shutdown, going down now!", 0);
                log("Calling to exit...", 0);

                send_toAll("Going down in 5sec! See you!", this.client_id);
                Thread.sleep(5000);
                log("Exiting! See you!", 0);
                System.exit(0);
            }

            exit();

        } catch (IOException | InterruptedException ioe) {
            log("IOException on socket listen: " + ioe, 2);
            ioe.printStackTrace();
        }
    }

    void exit()
    {
        log("Client with ID: " + this.client_id + " disconnected.", 0);
        clients.remove(this.client_id);

        try {

            this.in.close();
            this.out.close();
            this.server.close();

        } catch (IOException ioe) {
            log("IOException on socket listen: " + ioe, 2);
            ioe.printStackTrace();
        }
    }

    void send_toAll(String msg, int id)
    {
        for (int i =0; i < clients.size(); i++)
        {
            clients.get(i).send(msg, id);
        }
    }

    void send(String msg, int id)
    {
        out.println("Somebody(ID: " + id + ") says: " + msg);
    }

    void log(String msg, int lvl)
    {
        if(lvl == 0)
        {
            System.out.println("[Notice][" + date.toString() + "] - " + msg);
        }else if(lvl == 1)
        {
            System.out.println("[Warn][" + date.toString() + "] - " + msg);
        }else if(lvl == 2)
        {
            System.out.println("[Error][" + date.toString() + "] - " + msg);
        }
    }
}

谢谢你的帮助!

2 个答案:

答案 0 :(得分:0)

您需要一种方法来跟踪doComm的所有实例。以下是示例解决方案:

  1. static
  2. 中添加一个Collection字段,其中包含ArrayList(例如doCommsdoComm
  3. this的构造函数中添加out.println到该静态集合
  4. 将用于发送消息(doComm)的代码移至doComm
  5. 中的单独方法
  6. String添加一些接受doComm参数的方法,然后遍历{{1}}个实例的静态集合并调用新方法发送消息
  7. 我希望它有所帮助..

答案 1 :(得分:0)

javadeveloper的答案将实现您想要做的事情但是在关闭套接字后不要忘记删除doComm引用。

然而,听起来你需要的是一个多播套接字。见Multicast Socket