Я обнаружил несколько случаев моей проблемы, но, к сожалению, не могу ее исправить после многих часов.В основном у меня есть приложение группового чата Socket, которое позволяет клиентам входить в систему, сервер использует базу данных для проверки входа в систему, а затем либо позволяет клиенту перейти на страницу чата, либо нет.После входа в систему нажимается кнопка «Подключить», чтобы инициализировать сокетное соединение для чата.Я добрался до стадии, когда у меня могло быть несколько клиентов, и каждый мог отправить сообщение, оно было бы принято сервером и отправлено всем клиентам, но другие клиенты могли прочитать его только при нажатии кнопки «Отправить».С тех пор я попробовал много способов заставить его работать синхронизированным, но теперь я вернулся к точке, где сервер не будет возвращать сообщения обратно.
Я хотел бы получить совет о том, как изменить сервер, чтобы получать сообщения, полученные от клиентов, и передавать их всем клиентам.
PS Это мой первый пост, заранее спасибо.
Код сервера и обработчика ----------------------
public class ServerHandler extends JFrame {
private static final long serialVersionUID = 1L;
private JPanel contentPane;
static JTextField tfSend;
public static JTextArea textArea;
private JScrollPane scrollPane;
static JButton btnSend;
private JButton btnSettings;
/**
* Launch the application.
* @throws IOException
*/
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ServerHandler frame = new ServerHandler();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
// server is listening on port 8000
ServerSocket ss = new ServerSocket(8000);
while (true)
{
Socket s = null;
try
{
//socket object to receive incoming client requests
s = ss.accept();
textArea.setText(textArea.getText() + "\nA new client connected : " + s);
//obtaining input and out streams
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
DataOutputStream dos = new DataOutputStream(s.getOutputStream());
DataInputStream dis = new DataInputStream(s.getInputStream());
textArea.setText(textArea.getText() + "\nAssigning new thread for this client");
// create a new thread object
ClientHandler t = new ClientHandler(s, ois, oos, dos,dis);
//Invoking the start() method
t.start();
}
catch (Exception e){
s.close();
ss.close();
e.printStackTrace();
}
}
}
public ServerHandler() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 700, 500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setBackground(Color.LIGHT_GRAY);
setContentPane(contentPane);
contentPane.setLayout(null);
btnSend = new JButton("Send");
btnSend.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnSend.setBounds(542, 404, 117, 29);
contentPane.add(btnSend);
btnSettings = new JButton("Settings");
btnSettings.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnSettings.setBounds(542, 30, 117, 29);
contentPane.add(btnSettings);
tfSend = new JTextField();
tfSend.setBounds(45, 404, 490, 26);
contentPane.add(tfSend);
tfSend.setColumns(10);
tfSend.setEditable(false);
textArea = new JTextArea();
scrollPane = new JScrollPane(textArea);
scrollPane.setLocation(47, 71);
scrollPane.setAutoscrolls(true);
scrollPane.setSize(612,322);
contentPane.add(scrollPane);
textArea.setEditable(false);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
lblNewLabel.setBounds(26, 23, 652, 429);
contentPane.add(lblNewLabel);
}
}
class ClientHandler extends Thread {
//thread conns
private ObjectInputStream ois;
private ObjectOutputStream oos;
private DataOutputStream dos;
private DataInputStream dis;
private Socket s;
//database conns
static Connection c;
static Statement stmt;
static Connection c1;
static Statement stmt1;
static Connection c2;
static Statement stmt2;
public ClientHandler(Socket s, ObjectInputStream ois, ObjectOutputStream oos, DataOutputStream dos2, DataInputStream dis2) {
this.s = s;
this.ois = ois;
this.oos = oos;
this.dos = dos2;
this.dis = dis2;
}
@Override
public void run()
{
try {
System.out.println("running");
checkUTF();
} catch (IOException e1) {
e1.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public void checkUTF() throws IOException, SQLException {
while(true) {
String check = null;
check = dis.readUTF();
System.out.println("check");
if (check!= null) {
System.out.println("switching");
try {
switch(check) {
case "chat":
System.out.println("chatting");
chat();
case "Login":
try {
System.out.println("checking login");
checkLogin();
} catch (SQLException e1) {
e1.printStackTrace();
}
}}finally {
System.out.println("ending");
close();
}
}else {
}
}
}
public void chat() throws IOException {
dos.writeUTF("chat");
dos.flush();
ServerHandler.tfSend.setEditable(true);
while(s.isClosed()==false) {
String check = null;
check = dis.readUTF();
if (check!= null) {
if(check.equals("close")){
dos.writeUTF("close");
break;
}else{
dos.writeUTF(check);
}
}
}
}
public void close() throws IOException {
dos.close();
dis.close();
oos.close();
ois.close();
s.close();
}
public void checkLogin() throws SQLException {
ClientStuff.LoginObject login = null;
System.out.println("here");
try {
login = (LoginObject) ois.readObject();
System.out.println(login.getName() + login.getPassword());
String username = login.getName().trim();
String password = login.getPassword().trim();
if((checkLoginDetails(username,password))==true) {
closeDatabase();
String status = "Found";
dos.writeUTF(status);
dos.flush();
System.out.println("ending2");
}else {
closeDatabase();
String status = "Not Found";
dos.writeUTF(status);
dos.flush();
System.out.println("ending3");
close();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public static boolean checkLoginDetails(String username, String password) throws SQLException {
startDatabaseConnections();
stmt2 = c2.createStatement();
ResultSet rs = stmt2.executeQuery("SELECT * FROM CLIENTINFO WHERE USERNAME = '"+username+"' AND PASSWORD = '"+password+"';");
while ( rs.next() ) {
return true;
}
rs.close();
return false;
}
public static void startDatabaseConnections() {
try {
Class.forName("org.sqlite.JDBC");
c = DriverManager.getConnection("jdbc:sqlite:ServerInfo");
System.out.println("Opened database successfully");
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
try {
Class.forName("org.sqlite.JDBC");
c1 = DriverManager.getConnection("jdbc:sqlite:ClientConvo");
System.out.println("Opened database successfully");
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
try {
Class.forName("org.sqlite.JDBC");
c2 = DriverManager.getConnection("jdbc:sqlite:ClientInfo");
System.out.println("Opened database successfully");
} catch ( Exception e ) {
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
System.exit(0);
}
}
public static void closeDatabase() throws SQLException {
c.close();
c1.close();
c2.close();
System.out.println("Databases Closed");
}
}
Код входа клиента --------------
public class UserLogin extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
*
*/
static UserLogin frame;
private JPanel contentPane;
private static JTextField tfUsername;
private static JTextField tfPassword;
static boolean yes = false;
static JButton btnNewUser = new JButton("New User");
static JButton btnLogin = new JButton("Login");
static Socket login = new Socket();
private static String serverIP = "127.0.0.1";
static ObjectOutputStream oos;
static ObjectInputStream ois;
static DataOutputStream dos;
static DataInputStream dis;
static String status = null;
/**
* Launch the application.
* @throws IOException
* @throws UnknownHostException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws UnknownHostException, IOException, ClassNotFoundException {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
frame = new UserLogin();
if(frame.isVisible()==false) {
frame.setVisible(true);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public void foundUser(String status) {
if (status.equals("Found")) {
frame.setVisible(false);
dispose();
new UserChat().setVisible(true);
}else if(status.equals("Not Found")) {
close();
tfUsername.setText("Not Found");
tfPassword.setText("Not Found");
}
}
public void close(){
System.out.println("closing");
try {
login.close();
dos.close();
dis.close();
oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void connectServer() throws IOException {
System.out.println("start stream setup");
login = new Socket(InetAddress.getByName(serverIP), 8000);
}
public void setupStreams() throws IOException {
System.out.println("start stream setup 2");
oos = new ObjectOutputStream(login.getOutputStream());
System.out.println("obj output stream setup");
ois = new ObjectInputStream(login.getInputStream());
System.out.println("obj input stream setup");
dos = new DataOutputStream(login.getOutputStream());
System.out.println("data output stream setup");
dis = new DataInputStream(login.getInputStream());
System.out.println("data input stream setup");
}
/**
* Create the frame.
* @throws IOException
*/
public UserLogin() throws IOException {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 700, 500);
contentPane = new JPanel();
contentPane.setBackground(Color.LIGHT_GRAY);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
btnNewUser.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnNewUser.setBounds(373, 294, 117, 29);
contentPane.add(btnNewUser);
btnLogin.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnLogin.setBounds(373, 253, 117, 29);
contentPane.add(btnLogin);
tfUsername = new JTextField();
tfUsername.setBounds(255, 175, 235, 26);
contentPane.add(tfUsername);
tfUsername.setColumns(10);
tfPassword = new JTextField();
tfPassword.setColumns(10);
tfPassword.setBounds(255, 213, 235, 26);
contentPane.add(tfPassword);
JLabel lblUsername = new JLabel("Username");
lblUsername.setBounds(127, 180, 104, 16);
contentPane.add(lblUsername);
JLabel lblPassword = new JLabel("Password");
lblPassword.setBounds(127, 218, 104, 16);
contentPane.add(lblPassword);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
lblNewLabel.setBounds(26, 23, 646, 429);
contentPane.add(lblNewLabel);
btnNewUser.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
new UserReg().setVisible(true);
}
}
);
btnLogin.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
LoginObject userLogin = new LoginObject(tfUsername.getText(),tfPassword.getText());
System.out.println(userLogin.getName() + userLogin.getPassword());
try {
connectServer();
setupStreams();
dos.writeUTF("Login");
dos.flush();
System.out.println("login");
oos.writeObject(userLogin);
oos.flush();
System.out.println("userlogin");
} catch (IOException e) {
e.printStackTrace();
}
String status = null;
try {
status = dis.readUTF();
System.out.println(status);
} catch (IOException e) {
e.printStackTrace();
}
System.out.println(status);
foundUser(status);
}
}
);
}}
Код чата клиента ---------
public class UserChat extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private static JTextField tfSend;
private static JTextArea textArea;
private JScrollPane scrollPane;
private static JButton btnSend;
private JButton btnSettings;
private JButton btnLogout;
private JButton btnGetChat;
String messageIn = "";
private static Socket login = new Socket();
private static String serverIP = "127.0.0.1";
static ObjectOutputStream oos;
static ObjectInputStream ois;
static DataOutputStream dos;
static DataInputStream dis;
static String status = null;
private JButton btnConnect;
/**
* Launch the application.
* @throws IOException
*/
public static void main(String[] args) throws IOException {
EventQueue.invokeLater(new Runnable() {
public void run() {
UserChat frame = new UserChat();
if(frame.isVisible()==false) {
frame.setVisible(true);
}
}
});
System.out.println("mainnn");
}
public static void connectServer() throws IOException {
textArea.setText(textArea.getText()+"start stream setup\n");
login = new Socket(InetAddress.getByName(serverIP), 8000);
textArea.setText(textArea.getText()+"start stream setup 2\n");
oos = new ObjectOutputStream(login.getOutputStream());
textArea.setText(textArea.getText()+"obj output stream setup\n");
ois = new ObjectInputStream(login.getInputStream());
textArea.setText(textArea.getText()+"obj input stream setup\n");
dos = new DataOutputStream(login.getOutputStream());
textArea.setText(textArea.getText()+"data output stream setup\n");
dis = new DataInputStream(login.getInputStream());
textArea.setText(textArea.getText()+"data input stream setup\n");
}
public static void whileChatting() throws IOException {
tfSend.setEditable(true);
if(login.isClosed()==false) {
btnSend.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
String sendText = "Client - ";
sendText += tfSend.getText();
try {
dos.writeUTF(sendText);
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
tfSend.setText("");
}
}
);
Thread t = new MsgHandler(login, ois, oos, dis,dos, textArea);
t.start();
}
}
/**
* Create the frame.
*/
public UserChat() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 700, 500);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setBackground(Color.LIGHT_GRAY);
setContentPane(contentPane);
contentPane.setLayout(null);
btnSend = new JButton("Send");
btnSend.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnSend.setBounds(542, 404, 117, 29);
contentPane.add(btnSend);
btnConnect = new JButton("Connect");
btnConnect.setBounds(165, 31, 117, 29);
contentPane.add(btnConnect);
btnSettings = new JButton("Settings");
btnSettings.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnSettings.setBounds(542, 30, 117, 29);
contentPane.add(btnSettings);
btnLogout = new JButton("Logout");
btnLogout.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnLogout.setBounds(37, 30, 117, 29);
contentPane.add(btnLogout);
btnGetChat = new JButton("Get Chat");
btnGetChat.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
btnGetChat.setBounds(417, 30, 117, 29);
contentPane.add(btnGetChat);
tfSend = new JTextField();
tfSend.setBounds(45, 404, 490, 26);
contentPane.add(tfSend);
tfSend.setColumns(10);
tfSend.setEditable(false);
textArea = new JTextArea();
scrollPane = new JScrollPane(textArea);
scrollPane.setLocation(47, 71);
scrollPane.setAutoscrolls(true);
scrollPane.setSize(612,322);
contentPane.add(scrollPane);
textArea.setEditable(false);
JLabel lblNewLabel = new JLabel("");
lblNewLabel.setBorder(new BevelBorder(BevelBorder.RAISED, null, null, null, null));
lblNewLabel.setBounds(26, 23, 652, 429);
contentPane.add(lblNewLabel);
btnLogout.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
try {
dos.writeUTF("logout");
dos.flush();
System.out.println("Servers Closed");
dispose();
setVisible(false);
UserLogin.main(null);
} catch (IOException | ClassNotFoundException e) {
e.printStackTrace();
}
}
}
);
btnConnect.addActionListener(
new ActionListener(){
public void actionPerformed(ActionEvent event){
try {
connectServer();
dos.writeUTF("chat");
dos.flush();
String chat = dis.readUTF();
System.out.println(chat);
if(chat.equals("chat")) {
System.out.println(chat);
btnConnect.setVisible(false);
whileChatting();
}
} catch (IOException e) {
e.printStackTrace();
System.out.println("Here");
}
}
}
);
}
}
class MsgHandler extends Thread{
final ObjectInputStream ois;
final ObjectOutputStream oos;
final Socket s;
DataOutputStream dos;
DataInputStream dis;
JTextArea textArea;
public MsgHandler(Socket s, ObjectInputStream ois, ObjectOutputStream oos, DataInputStream dis2, DataOutputStream dos2,
JTextArea textArea){
this.s = s;
this.ois = ois;
this.oos = oos;
this.dis = dis2;
this.dos = dos2;
this.textArea = textArea;
}
public void run(){
try {
checkUTF();
} catch (IOException e1) {
e1.printStackTrace();
}
}
public void checkUTF() throws IOException {
System.out.println("running to listen");
while(s.isClosed()==false) {
String check = null;
check = dis.readLine();
if (check!= null) {
if(check.equals("close")){
close();
break;
}else{
textArea.append("\n"+check);
System.out.println("receive message from the server");
}
}
}
}
public void close(){
System.out.println("closing");
try {
s.close();
dos.close();
dis.close();
oos.close();
ois.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}