【问题标题】:Multithreaded server-client application sends multiple time the response多线程服务器-客户端应用程序多次发送响应
【发布时间】:2015-11-12 19:51:24
【问题描述】:

我有一个多线程服务器-客户端应用程序。当我尝试在客户端之间进行通信时,我尝试发送的消息被发送多次(例如,当我有 2-3 个客户端连接时,消息被发送 2 次,当我有 10 个客户端连接时,消息被发送 6 次)。代码如下:

ServerProtocol

public class ServerProtocol {

    private String nick;
    private final ClientConn conn;

    private static final HashMap < String, ClientConn > nicks = new HashMap < > ();
    private static final String msg_WELCOME = "You are connected to server";
    private static final String msg_OK = "Message sent";
    private static final String msg_NICK_IN_USE = "Nick in use";

    private static final String msg_SEND_FAILED = "Failed to send";

    public ServerProtocol(ClientConn c) {
        nick = null;
        conn = c;
    }

    private byte[] authenticate(String mesaj) {

        String id = mesaj.substring(0, 1);

        if (!nicks.containsKey(id)) {
            nicks.put(id, this.conn);
            System.out.println(id + " joined.");
            this.nick = id;

            return msg_WELCOME.getBytes();

        } else {
            return msg_NICK_IN_USE.getBytes();
        }

    }

    public boolean sendMsgCSP(String recipient, String msg) throws IOException {
        if (nicks.containsKey(recipient)) {
            int e = nicks.size();
            for (int i = 0; i < e; i++) {
                ClientConn c = nicks.get(recipient);
                //c.sendMsgCC(nick.getBytes());
                c.sendMsgCC(msg.getBytes());
                System.out.println("message sent: " + msg + " to client " + recipient);
            }
            return true;
        } else {
            return false;
        }
    }

    public byte[] process(byte[] msg) throws IOException {
        //System.out.println(Arrays.toString(msg));
        String mesaj = new String(msg);
        if (!nicks.containsKey(nick)) {
            return authenticate(mesaj);
        }

        System.out.println("message:" + mesaj);

        if (sendMsgCSP(mesaj.substring(0, 1), mesaj.substring(1))) {
            return msg_OK.getBytes();
        } else {
            return msg_SEND_FAILED.getBytes();
        }
    }
}

ClientConn 类:

public class ClientConn implements Runnable {

    private final Socket clients;
    private OutputStream os;
    private DataOutputStream dos;
    private InputStream is;
    private DataInputStream dis;

    ClientConn(Socket client) {
        this.clients = client;

        try {
            is = clients.getInputStream();
            dis = new DataInputStream(is);
            os = clients.getOutputStream();
            dos = new DataOutputStream(os);

        } catch (IOException ex) {
            Logger.getLogger(ClientConn.class.getName()).log(Level.SEVERE, null, ex);
        }

    }

    @Override
    public void run() {

        byte[] read, response;
        ServerProtocol protocol = new ServerProtocol(this);

        try {

            while (true) {
                read = readBytes();

                //System.out.println(Arrays.toString(rd));
                //System.out.println("message received: " + Arrays.toString(read));
                response = protocol.process(read);

                sendMsgCC(response);


            }
        } catch (IOException ex) {
            System.out.println(ex);

        }
    }

    public void sendMsgCC(byte[] myByteArray) throws IOException {
        int start = 0;
        int len = myByteArray.length;
        if (len < 0) {
            throw new IllegalArgumentException("Negative length not allowed");
        }
        if (start < 0 || start >= myByteArray.length) {
            throw new IndexOutOfBoundsException("Out of bounds: " + start);
        }

        dos.writeInt(len);
        if (len > 0) {
            dos.write(myByteArray, start, len);

        }
    }

    public byte[] readBytes() throws IOException {
        int len = dis.readInt();
        byte[] data = new byte[len];

        if (len > 0) {
            dis.readFully(data);
        }

        return data;

    }

}

我认为问题出在 sendMsgCC 方法上,但我想不通

【问题讨论】:

    标签: java multithreading hashmap server client


    【解决方案1】:

    这里:

       for (int i = 0; i < e; i++) {
            ClientConn c = nicks.get(recipient);
            c.sendMsgCC(msg.getBytes());
            System.out.println("message sent: " + msg + " to client " + recipient);
        }
    

    您向收件人发送消息的次数与连接的客户端数量一样多。为什么是循环?

    此外,您的代码在没有同步或锁定的情况下从多个线程读取和写入共享数据,请为问题做好准备。

    【讨论】:

      猜你喜欢
      • 2015-09-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-12-21
      相关资源
      最近更新 更多