0

我需要你的帮助 :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);
        }
    }
}

谢谢你的帮助!

4

2 回答 2

0

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

  1. 在类中添加一个static带有一些Collection(例如ArrayList)的字段doComms
  2. doComm添加this到该静态集合的构造函数中
  3. 将用于发送消息 ( out.println) 的代码移动到一个单独的方法中doComm
  4. 添加一些方法来doComm接受String参数,然后遍历doComm实例的静态集合并调用新方法来发送消息

我希望它有帮助..

于 2013-05-11T15:43:43.647 回答
0

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

但是,听起来您需要的是多播套接字。请参阅多播套接字

于 2013-05-11T16:02:59.637 回答