【问题标题】:Issue with Threads/sockets and MySql (Java)线程/套接字和 MySql (Java) 的问题
【发布时间】:2016-03-08 09:40:40
【问题描述】:

我对我的 java 老师的一个练习有很大的疑问。 理论上演练必须具备以下几点:

-套接字 -客户 -服务器 - 服务器使用 MySql 做某事 -登录 -md5 保存密码 -安全套接字

有了这个,我决定在理论上聊天应该很容易,但是......我完全迷路了。

我或多或少做了基本的(安全套接字、服务器、客户端),但即使这样也不起作用,但理论上 IDE 不会失败应该没问题。

有人可以帮助我吗?

代码如下:

ChatClient 这使客户端工作,加载界面和功能:

public class ChatClient 
{


    private Socket s;

    private ClientPanel panel;


    public static void main(String[] args) 
    {
        new ChatClient();
    }

    public ChatClient()
    {
        try
        {
            Window();
            s = new Socket("localhost" , 5557);
            ClientControl control = new ClientControl(s, panel);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private void Window()
    {
        JFrame v = new JFrame();
        panel = new PanelCliente(v.getContentPane());
        v.pack();
        v.setVisible(true);
        v.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    }
}

ServerChat 这创建了一个带有安全套接字的服务器聊天作为练习的必要条件之一:

public class ServerChat extends Thread
{
    public static void main(String[] args) 
    {
            int port= 5090;

            SSLServerSocketFactory sslserver = (SSLServerSocketFactory) SSLServerSocketFactory.getDefault();
            try 
            {
                SSLServerSocket sslsocket = (SSLServerSocket)sslserver.createServerSocket();

                InetSocketAddress socketAddress = new InetSocketAddress("localhost" , port);

                while(true)
                    {

                        SSLSocket socket = (SSLSocket)sslsocket.accept();
                        System.out.println("Client:  " + socket.getInetAddress().getHostName() + " Conected");

                    }   
            } 
            catch (IOException e) 
            {
                e.printStackTrace();
            }           

    }

}


public class ClientControl implements ActionListener, Runnable
{

    private DataInputStream dataInput;

    private DataOutputStream dataOutput;

    private ClientPanel panel;

    public ClientControl (Socket s, ClientPanel panel)
    {
        this.panel = panel;

        try
        {
            dataInput = new DataInputStream(s.getInputStream());
            dataOutput = new DataOutputStream(s.getOutputStream());
            panel.addActionListener(this);
            Thread t = new Thread(this);
            t.start();

        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void actionPerformed (ActionEvent event)
    {
        try
        {
            dataOutput.writeUTF(panel.getTexto());
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

    public void run()
    {
        try
        {
            String text = dataInput.readUTF();
            panel.addTexto(text);
            panel.addTexto("\n");

        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }

}

客户端线程理论上可以将客户端作为线程运行并实现其功能:

public class ClientThread implements Runnable, ListDataListener
{

    private DefaultListModel conversation;

    private Socket s;

    private DataInputStream dataInput;

    private DataOutputStream dataOutput;

    public ClientThread (DefaultListModel conversation, Socket s)
    {
        this.conversation = conversation;
        this.s = s;

        try
        {
            dataInput = new DataInputStream(s.getInputStream());
            dataOutput = new DataOutputStream(s.getOutputStream());
            conversation.addListDataListener(this);
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void run()
    {
        try
        {
            while (true)
            {
                String text = dataInput.readUTF();
                System.out.println(text);
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    public void intervalAdded(ListDataEvent e)
    {
        String text = (String) conversation.getElementAt(e.getIndex0());

        try
        {
            dataOutput.writeUTF(text);
        }
        catch(Exception ex)
        {
            ex.printStackTrace();
        }
    }

    @Override
    public void contentsChanged(ListDataEvent arg0) 
    {
    }

    @Override
    public void intervalRemoved(ListDataEvent arg0) 
    {   
    }
}

下面的客户端面板基本上用 JSwing 做了一个简单的设计来创建和界面,你可以看到对话,你可以写任何你想要的:

public class ClientPanel
{

    private JScrollPane scroll;

    private JTextArea textArea;

    private JTextField textField;

    private JButton button;


    public ClientPanel(Container cont)
    {
        cont.setLayout(new BorderLayout());
        textArea = new JTextArea();
        scroll = new JScrollPane(textArea);

        JPanel panel = new JPanel(new FlowLayout());
        textField = new JTextField(50);
        button = new JButton("Send");
        panel.add(textField);
        panel.add(button);

        cont.add(scroll, BorderLayout.CENTER);
        cont.add(panel, BorderLayout.SOUTH);
    }

    public void addActionListener (ActionListener action)
    {
        textField.addActionListener(action);
        button.addActionListener(action);
    }

    public void addTexto (String text)
    {
        textArea.append(text);
    }

    public String getTexto()
    {
        String text = textField.getText();
        textField.setText(text);
        return text;
    }
}

如何将数据库添加到登录用户? 如何添加 Md5 来保护密码? 我怎样才能让这一切一起工作?

这是我的问题

【问题讨论】:

    标签: java mysql multithreading sockets


    【解决方案1】:

    你有一个服务器和客户端,想写一个聊天。因此,服务器是中心,并保持与存储所有持久数据的数据库的连接。密码不存储为纯文本,只有它的 md5 哈希存储在数据库中。 此外,只有服务器拥有与数据库的连接。

    这回答了在哪里使用MD5 以及数据库的主人是谁。

    您已经创建了一个SeverChat。那家伙负责倾听新客户的连接。如果一个新客户端想要连接,ServerChat 必须生成一个新的ClientController

    您的ClientControl 看起来不像我的意思。 ClientControll 负责从他连接的特定客户端获取请求,处理请求并向客户端发送应答。

    这意味着您需要某种协议。您可以使用ObjectStreams 将对象从客户端发送到服务器,反之亦然。 这样可以更轻松地定义协议。

    了解ClientController

      class ClientController extends Thread {
    
        private final ObjectInputStream dataInput;
        private final ObjectOutputStream dataOutput;
        private boolean loggedIn = false;
    
        ClientController(ObjectInputStream dataInput, ObjectOutputStream dataOutput) {
          this.dataInput = dataInput;
          this.dataOutput = dataOutput;
        }
    
        @Override
        public void run() {
          try {
            boolean stayConnected = true;
            while (stayConnected) {
              Object data = dataInput.readObject();
              if (data instanceof LoginAction) {
    //          check data an do login
                this.loggedIn = true;
                dataOutput.write(new LoginResponse(/* response data */));
              }
              if (data instanceof RequestChatDataAction) {
                if (this.loggedIn) {
                  dataOutput.write(new NotLoggedInResponse());
                } else {
                  dataOutput.write(new ChatDataResponse(/* chat data.. */));
                }
              }
            }
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
    

    LoginActionLoginResponse a.s.o.对象定义您的协议。你需要更多的对象来实现所有的特性,这些对象必须实现java.io.Serializable。否则,您将无法通过网络发送它们。

    您还必须编写对应部分 - 客户端。

    客户端启动,连接到服务器并尝试登录。如果登录成功,客户端等待新的聊天数据并显示。 如果用户输入内容,此数据将发送到服务器并添加到“全球”聊天数据中。

    我建议不要在客户端-服务器通信完成之前添加 gui 元素。您可以使用System.outSystem.in 与用户进行交互。

    所以,希望对你有所帮助。

    此外,SO 不适用于以下问题:做我的作业。我看到你已经拿了tour

    阅读How to create a Minimal, Complete, and Verifiable example 将不胜感激。

    【讨论】:

    • 投票如果对您有帮助,我的回答将不胜感激。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-21
    • 2013-10-14
    • 1970-01-01
    • 2016-12-27
    • 2015-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多