Сервер дублирует сообщения

239
10 мая 2018, 08:33

Приложение-чатик клиент/сервер.

Я просто не знаю почему это приисходит Уже всё перепробовал

Все потоки останавливаются, но при реконнекте сообщений отправляется на один больше, чем было до реконнекта

Код клиента:

package client;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
import server.ServerFrame;
import useful.Useful;
public class ClientFrame extends JFrame {
private static final long serialVersionUID = -5586831200368805366L;
static JPanel contentPane;
static JTextField InputField;
static JTextField Port;
static JTextField Ip;
static String IpAdress;
static int ServerPort;
static InetAddress ServerIp;
static JButton Send;
static String textToSend;
static JTextField Username;
static JTextArea ChatArea;
private boolean Connected;
private Thread cThread;
InputStream sis;
OutputStream sos;
Socket socket;
DataInputStream in;
DataOutputStream out;
int client_number;
private JLabel BackGround;
private String user_name;
private int user_id;
private JButton Connect;
public static void buildClientFrame() {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Throwable e) {
        e.printStackTrace();
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                ClientFrame frame = new ClientFrame();
                Useful.center(frame);
                frame.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("client.png")));
                frame.setVisible(true);
            } catch (Exception e) {e.printStackTrace();}
        }
    });
}
/**
 * Create the frame.
 * @throws Exception 
 */
public ClientFrame() throws Exception { 
    this.addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            try {socket.close();} catch (Exception e1) {System.err.println("Error closing socket on exit! " + e1);}
            System.exit(0);
        }
    });
    setResizable(false);
    setTitle("Client");
    setBounds(100, 100, 390, 415);
    contentPane = new JPanel();
    setContentPane(contentPane);
    contentPane.setLayout(null);
    Username = new JTextField();
    Username.setText("Username");
    Username.setFont(new Font("Arial", Font.PLAIN, 12));
    Username.setColumns(10);
    Username.setBounds(10, 11, 65, 20);
    contentPane.add(Username);
    ChatArea = new JTextArea();
    ChatArea.setFont(new Font("Arial", Font.PLAIN, 14));
    ChatArea.setEditable(false);
    ChatArea.setBounds(10, 42, 364, 302);
    contentPane.add(ChatArea);
    JScrollPane sp = new JScrollPane(ChatArea);
    sp.setBounds(10, 42, 364, 302);
    contentPane.add(sp);
    InputField = new JTextField();
    Useful.setFieldTip(InputField, "Enter your message!");
    InputField.setFont(new Font("Arial", Font.PLAIN, 12));
    InputField.setBounds(10, 355, 243, 20);
    contentPane.add(InputField);
    Send = new JButton("Send!");
    Send.setBounds(263, 355, 111, 20);
    contentPane.add(Send);
    Send.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            textToSend = InputField.getText();
        }
    });
    Port = new JTextField();
    Port.setText("3333");
    Port.setFont(new Font("Arial", Font.PLAIN, 12));
    Port.setColumns(10);
    Port.setBounds(188, 11, 65, 20);
    contentPane.add(Port);
    Ip = new JTextField();
    Ip.setText("localhost");
    Ip.setFont(new Font("Arial", Font.PLAIN, 12));
    Ip.setColumns(10);
    Ip.setBounds(85, 11, 93, 20);
    contentPane.add(Ip);
    URL ico = getClass().getClassLoader().getResource("11.png");
            Connect = new JButton("Connect");
            Connect.setBounds(263, 11, 111, 22);
            contentPane.add(Connect);
            Connect.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent arg0) {
                    if(Connected==false) {
                        //Connect.setEnabled(false);
                        cThread = new Thread(new Runnable() {
                            public void run() {
                                try {
                                    ChatArea.append("Trying to connect..."+"\n");
                                    try {
                                        IpAdress = Ip.getText().trim();
                                        ServerPort = Integer.valueOf(Port.getText().trim());
                                        try {
                                            ServerIp = InetAddress.getByName(IpAdress);
                                        }catch (UnknownHostException e2) {
                                            ChatArea.append("Unable to connect! Invalid ip!"+"\n");
                                            Connect.setText("Connect");
                                            Connected = false;
                                            Connect.setEnabled(true);
                                            return;
                                        }
                                        System.out.println(String.valueOf(ServerIp) + "lolo" + ServerPort);
                                        socket = new Socket(ServerIp, ServerPort);
                                        ChatArea.append("Establishing connection..."+"\n");
                                        sis = socket.getInputStream();
                                        sos = socket.getOutputStream();
                                        in = new DataInputStream(sis);
                                        out = new DataOutputStream(sos);
                                        ChatArea.append("Streams created..."+"\n");
                                        int clientID = Useful.randomInt(Integer.MAX_VALUE);
                                        String ClientNAME = Username.getText();
                                        String user_creditals = ClientNAME + ":NAMEANDID:" + clientID;
                                        out.writeUTF(user_creditals);
                                        user_id = clientID;
                                        user_name = ClientNAME;
                                        ChatArea.append("Connection succesful!"+"\n");
                                        Connected = true;
                                        Connect.setText("Disconnect");                                          
                                        Send.addActionListener(new ActionListener() {
                                            public void actionPerformed(ActionEvent e) {
                                                textToSend = Username.getText() + ">> " + InputField.getText() + "\n";
                                                try {
                                                    System.out.println("Probably sent:  "+textToSend);
                                                    out.writeUTF(textToSend);
                                                    textToSend = null;
                                                    out.flush();
                                                } catch (IOException e1) {}
                                            }
                                        });
                                        while(true) {
                                            String textToAdd = in.readUTF();
                                            System.out.println(textToAdd + " - was sent by srvr");
                                            ChatArea.append(textToAdd);
                                            textToAdd = null;
                                        }
                                    } catch(IOException e) {
                                        ChatArea.append("Unable to connect! No server found!"+"\n");
                                        Connect.setText("Connect");
                                        Connect.setEnabled(true);
                                        stopConnection();
                                        cThread.stop();
                                        Connected = false;
                                    }catch (NumberFormatException ex) {
                                        ChatArea.append("Unable to connect! Invalid ip!"+"\n");
                                        Connect.setText("Connect");
                                        Connect.setEnabled(true);
                                        cThread.interrupt();
                                        stopConnection();
                                        cThread.stop();
                                        Connected = false;}

                                    //Cut from here
                                }catch(Exception e) {return;}
                            }
                        });cThread.start();
                    }else {
                        try {
                            out.writeUTF(user_name+":Disconnected:"+user_id);
                            stopConnection();
                            cThread.stop();
                        } catch (IOException e) {}
                    }
                }
            });
    BackGround = new JLabel("");
    BackGround.setIcon(new ImageIcon(ico));
    BackGround.setBounds(0, 0, 384, 386);
    contentPane.add(BackGround);
    Component btns[] = contentPane.getComponents();
    for(Component component : btns) {
        if(component instanceof JButton)
            component.setBackground(Color.GRAY);
    }
}
private void stopConnection() throws IOException {
    sis.close();
    sos.close();
    socket.close();
    //System.exit(0);
    Connected = false;
    Connect.setText("Connect");  //Username:Disconnected:1386415266
    }
}

Код сервера:

package server;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ServerSocket;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.*;

import useful.Useful;
public class ServerFrame extends JFrame {
private static final long serialVersionUID = 7833306565907828212L;
private JPanel contentPane;
private JTextField InputField;
private JButton start;
private JButton stop;
static JLabel status;
static DefaultListModel<String> dlm;
static JTextArea ChatArea;
private ServerSocket ss;
private static int Port;
private boolean server_enabled = false;
public static final String standby = "Standby...";
public static final String waiting = "Waiting for connection...";
public static final String connection_recieved = "Recieved connection!";
public static final String stopped = "Server stopped";
public static List<DataOutputStream> DataOut = new ArrayList<>();
public static List<Integer> IDs = new ArrayList<>();
static List<String> Usernames = new ArrayList<>();
private JTextField PortField;
private JButton SetPort;
private JLabel BackGround;
private JButton RefreshServer;
static boolean closing;
static Thread sockedThread;
/**
 * Create the frame.
 * @throws Exception 
 */
public static void buildServerFrame() {
    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (Exception e) {
        e.printStackTrace();
    }
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                ServerFrame frame = new ServerFrame();
                Useful.center(frame);
                frame.setIconImage(Toolkit.getDefaultToolkit().getImage(getClass().getClassLoader().getResource("chat.png")));
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

public ServerFrame() throws Exception {
    setResizable(false);
    setTitle("Server");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 390, 415);
    contentPane = new JPanel();
    //contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);
    /**
     *  Message area and Input field
     **/
    ChatArea = new JTextArea();
    ChatArea.setEnabled(false);
    ChatArea.setFont(new Font("Monospaced", Font.PLAIN, 13));
    ChatArea.setEditable(false);
    ChatArea.setBounds(10, 177, 364, 167);
    contentPane.add(ChatArea);
    JScrollPane sp = new JScrollPane(ChatArea);
    sp.setBounds(10, 177, 364, 167);
    contentPane.add(sp);
    InputField = new JTextField();
    InputField.setFont(new Font("Arial", Font.PLAIN, 12));
    InputField.setBounds(10, 352, 243, 25);
    contentPane.add(InputField);
    InputField.setColumns(10);
    /**
     *  Send button
     **/
    JButton Send = new JButton("New button");
    Send.setBounds(263, 352, 111, 25);
    contentPane.add(Send);
    /**
     * Labels don't touch
     */
    JLabel conn = new JLabel("Connected:");
    conn.setBounds(210, 9, 77, 14);
    contentPane.add(conn);
    JLabel lbl1 = new JLabel("Status:");
    lbl1.setBounds(10, 6, 45, 20);
    contentPane.add(lbl1);
    InputStream is = getClass().getClassLoader().getResourceAsStream("11.png");
    BufferedImage ico = ImageIO.read(is);
    JLabel lblNewLabel = new JLabel("Port");
    lblNewLabel.setBounds(11, 56, 46, 14);
    contentPane.add(lblNewLabel);
    BackGround = new JLabel("lol");
    BackGround.setIcon(new ImageIcon(ico));
    BackGround.setBounds(0, 0, 384, 386);
    /**
     * List of connected clients
     */
    dlm = new DefaultListModel<String>();
    //Poorly works :(
    JList<String> list = new JList<String>(dlm);
    list.setBounds(297, 8, 77, 135);
    contentPane.add(list);
    /**
     * Start / Stop server buttons
     */
    start = new JButton("Start server");
    start.setEnabled(false);
    start.setFont(new Font("Arial", Font.PLAIN, 11));
    start.setBounds(196, 120, 90, 23);
    contentPane.add(start);
    start.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            server_enabled = true;
            try{runServer();}catch(Exception ex){ex.printStackTrace();}
            stop.setEnabled(true);
            start.setEnabled(false);
            RefreshServer.setEnabled(true);
            status.setText(waiting);
            ChatArea.append("*Server started! Listening on port*"+Port+"*"+"\n");
            SetPort.setEnabled(false);
        }
    });
    stop = new JButton("Stop server");
    stop.setBounds(97, 120, 89, 23);
    stop.setVerticalTextPosition(SwingConstants.BOTTOM);
    stop.setHorizontalTextPosition(SwingConstants.CENTER);;
    stop.setEnabled(false);
    stop.setBorder(BorderFactory.createEmptyBorder());
    stop.setMargin(new Insets(0, 0, 0, 0));
    contentPane.add(stop);
    stop.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            server_enabled = false;
            try{runServer();}catch(Exception ex){ex.printStackTrace();}
            stop.setEnabled(false);
            start.setEnabled(true);
            RefreshServer.setEnabled(false);
            status.setText(stopped);
            dlm.removeAllElements();
            ChatArea.append("*Server stopped!*"+"\n");
            SetPort.setEnabled(true);
        }
    });
    /**
     * Button for disconnecting ppl
     */
    JButton Disconnect = new JButton("Disconnect");
    Disconnect.setEnabled(false);
    Disconnect.setFont(new Font("Tahoma", Font.PLAIN, 11));
    Disconnect.setBounds(196, 85, 89, 23);
    contentPane.add(Disconnect);
    /**
     * Label used to show status of server 
     */
    status = new JLabel("Stopped");
    status.setBounds(49, 6, 151, 20);
    contentPane.add(status);
    PortField = new JTextField();
    PortField.setText("3333");
    PortField.setBounds(10, 37, 45, 20);
    contentPane.add(PortField);
    PortField.setColumns(10);
    SetPort = new JButton("Set");
    SetPort.setBounds(58, 37, 37, 20);
    contentPane.add(SetPort);
    SetPort.setBorder(null);
    SetPort.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            String Portt = PortField.getText().trim();
            if(Portt.contains(".*\\d+.*") || Integer.valueOf(Portt) < 81) {
                return;
            }else if(Portt.equals(null)) {
                return;
            }else {
                Port = Integer.valueOf(Portt);
            }
            if(server_enabled==false) {
                SetPort.setEnabled(false);
                start.setEnabled(true);
            }else {
                SetPort.setEnabled(true);
                start.setEnabled(false);
            }
        }
    });
    RefreshServer = new JButton("Refresh");
    RefreshServer.setBounds(97, 85, 89, 23);
    RefreshServer.setEnabled(false);
    contentPane.add(RefreshServer);
    RefreshServer.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            stop.doClick();
            start.doClick();
            RefreshServer.setEnabled(false);
            Timer tm = new Timer(1000,new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    RefreshServer.setEnabled(true);
                }
            });tm.start(); 
        }
    });
    contentPane.add(BackGround);
    Component[] btns_col = contentPane.getComponents();
    for(Component component : btns_col) {
        if(component instanceof JButton) {
            component.setBackground(Color.GRAY);
        }
    }
}
@SuppressWarnings("deprecation")
public void runServer() throws Exception {
    if(server_enabled == true) {
        sockedThread = new Thread(new Runnable() {
            public void run() {
                try {
                    ss = new ServerSocket(Port);
                    System.out.println(waiting);
                    status.setText(waiting);
                    //System.out.println("Socket created!");
                    while(true) {
                        //Socket sOcket = ss.accept();
                        //System.out.println(connection_recieved);
                        new AcceptThread(ss.accept()).start();

                    }
                } catch (IOException ex){
                    ex.printStackTrace();
                }
            }   
        });
        sockedThread.start();
    }
    else {
            DataOut.clear();
            IDs.clear();
            Usernames.clear();
            ss.close();
            sockedThread.stop();
        }
    }
}

AccpectThread (принималка подключений):

package server;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
public class AcceptThread extends Thread{
Socket client_socket;
private List<DataOutputStream> DataOut = new ArrayList<>();
private List<Integer> IDs = new ArrayList<>();
private List<String> Usernames = new ArrayList<>();
private InputStream sis;
private OutputStream sos;
private DataInputStream in;
private DataOutputStream out;
boolean working = true;
public AcceptThread(Socket socket) {
    this.client_socket = socket;
    this.DataOut = ServerFrame.DataOut;
    this.IDs = ServerFrame.IDs;
    this.Usernames = ServerFrame.Usernames;
}
public void run() {
    try {
        //System.out.println(ServerFrame.connection_recieved);
//          ServerFrame.status.setText(ServerFrame.connection_recieved);
        sis = client_socket.getInputStream();
        sos = client_socket.getOutputStream();

        in = new DataInputStream(sis);
        out = new DataOutputStream(sos);
        DataOut.add(out);

        while (true) {
            ServerFrame.IDs = this.IDs;
            ServerFrame.Usernames = this.Usernames;
            ServerFrame.DataOut = this.DataOut;
            String InputLine = DataInputStream.readUTF(in);
            System.out.println(InputLine + "- is the input line");
            if(InputLine.contains(":NAMEANDID:")) {
                String[] x = InputLine.split(":NAMEANDID:");
                System.err.println(Integer.valueOf(x[1]));
                IDs.add(Integer.valueOf(x[1]));
                ServerFrame.dlm.addElement(x[0]);
                Usernames.add(x[0]);
                System.out.println("This client holds id of: "+x[1] + " and username " + x[0]);     
            }
            else if(InputLine.trim().contains(":Disconnected:")) {
                System.err.println(IDs.toString() + " -i");
                String[] y = InputLine.split(":");
                y[2] = y[2].replace("\n", "");
                //System.err.println(Arrays.toString(y));
                int discID = Integer.valueOf(y[2]);
                String discNAME = y[0];
                if(IDs.contains(Integer.valueOf(y[2]))) {
                System.err.println(DataOut.size());
                System.err.println(Usernames.size());
                System.err.println(IDs.toString() + " before " + Integer.valueOf(discID) + " val");
                int index = IDs.indexOf(Integer.valueOf(discID));
                IDs.remove(index);
                Usernames.remove(index);
                DataOut.remove(index);
                ServerFrame.dlm.removeElement(discNAME);
                System.err.println("Close!");
                in.close();
                out.close();
                sis.close();
                sos.close();
                client_socket.close();
                ServerFrame.closing=true;
                stop();
                }else {
                    //System.err.println(IDs.toString());
                System.out.println("ID does not match");}
            }
            else {
            ServerFrame.ChatArea.append((InputLine));
            send(InputLine);
            System.out.println(DataOut.size() + " - number of Output Streams");
            }
        }
    }catch (IOException ioException) {}
}
private void send(String message) {
    if(message.contains(":NAMEANDID:")) return;
    try {
        System.err.println(DataOut.size() + message);
    for(DataOutputStream out : DataOut) {
        out.writeUTF(message);
        System.out.println("Sent!");
        out.flush();
    }
    }catch(Exception ex) {System.err.println("OOpse!");}
    }
}

Запускаю через вызов методов buildServer/Client:

package run;
import java.io.IOException;
import javax.swing.JOptionPane;
import client.ClientFrame;
import server.ServerFrame;
public class Run {
public static void main(String[] args) throws Exception {
    int length = args.length;
    if(length!=0) {
        for (String string : args) {
            if(args.length>1) {System.out.println("nope");
            runWithSelect(); return;}
            else if(string.equalsIgnoreCase("-client")) {
                ClientFrame.buildClientFrame();
                return;
            } else if(string.equalsIgnoreCase("-server")) {
                ServerFrame.buildServerFrame();
                return;
            } else {
                runWithSelect();
            }
        }
    } else {
        runWithSelect();
    }
}
private static void runWithSelect() throws IOException {
    String[] choices = {"Client", "Server"};
    String input = (String)JOptionPane.showInputDialog(null, "Choose Runtime:", "Choose Runtime", JOptionPane.QUESTION_MESSAGE, null, choices, choices[0]);
    System.out.println(input);
    if(input==null) System.exit(0);
    else if(input.equals(choices[0])) ClientFrame.buildClientFrame();
    else if (input.equals(choices[1])) ServerFrame.buildServerFrame();
    }
}

Это весь мой код. Надеюсь кто-нибудь поймёт его и расскажет нубу что здесь не так

P.S useful - это из моей библиотеки, там метод ранодом и центровка окна на экране.

READ ALSO
Android Studio, не добавляет запись в БД Sqlite

Android Studio, не добавляет запись в БД Sqlite

Подскажите пожалуйста, почему может не добавляться запись в БД? Никакой ошибки не возникает, всё работает, но запись просто не добавляет

225
Таблица друзей в базе данных

Таблица друзей в базе данных

Как лучше всего составить таблицу друзей tb_friend в базе данныхОсновной запрос который будет использоваться это - является ли user1 другом user2 или...

194
Добавить строки из одной таблицы в другую [НЕ ОБЪЕДИНИТЬ]

Добавить строки из одной таблицы в другую [НЕ ОБЪЕДИНИТЬ]

Имеются три таблицы с пользователямиУ всех трёх таблиц есть user_id , его я и хочу получить из этих всёх трёх таблиц

238
Реализация ITSG-06

Реализация ITSG-06

Появилась необходимость реализовать ITSG-06 на C++Вопрос в том, хватит ли мне циклической перезаписи файла, в соответствии с алгоритмом, через...

198