簡體   English   中英

如何在服務器/客戶端(JFrame)中使用線程?

[英]How to use Thread inside server/client (JFrame)?

我想從我的代碼中發送/接收來自多個客戶端的消息( String對象)。

這是沒有嘗試使用線程的代碼(它從服務器/客戶端發送/接收消息)

ServerGui

package server;


import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.ServerSocket;
import java.net.Socket;

public class ServerGui extends javax.swing.JFrame {
    
    static ServerSocket serverSocket;
    static Socket clientSocket;
    static DataInputStream inputFromClient;
    static DataOutputStream outPutToClient;

    /** Creates new form ServerGui */
    public ServerGui() {
        initComponents();
    }

    private void sendActionPerformed(java.awt.event.ActionEvent evt) {                                     
        try{
            String sendMsg = "";
            sendMsg = msgText.getText().trim();
            outPutToClient.writeUTF(sendMsg);
            msgText.setText("");
        } catch (Exception e) {}
    }   

    public static void main(String args[]) {
        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ServerGui().setVisible(true);
            }
        });
        
        String msg = "";
        try {
            serverSocket = new ServerSocket(2021);
            clientSocket = serverSocket.accept();

            inputFromClient = new DataInputStream(clientSocket.getInputStream());
            outPutToClient = new DataOutputStream(clientSocket.getOutputStream());
            
            while (!msg.equalsIgnoreCase("quit")){
                msg = inputFromClient.readUTF();
                chatArea.setText(chatArea.getText().trim() + "\nClient: " + msg);
            }
            
        } catch (Exception e) {}
    }

    // Variables declaration - do not modify                     
    private static javax.swing.JTextArea chatArea;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField msgText;
    private javax.swing.JButton send;
    // End of variables declaration                   

}

Client

package client;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.net.Socket;

public class ClientGui extends javax.swing.JFrame {
    static Socket clientSocket;
    static DataOutputStream outputToServer;
    static DataInputStream inputFromServer;
    
    public ClientGui() {
        initComponents();
    }

    private void sendActionPerformed(java.awt.event.ActionEvent evt) {                                     
        try{
            String sendMsg = "";
            sendMsg = msgText.getText().trim();
            outputToServer.writeUTF(sendMsg);
            msgText.setText("");
        } catch (Exception e) {}
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new ClientGui().setVisible(true);
            }
        });
        
        try {
            clientSocket = new Socket("127.8.8.1", 2021);
            inputFromServer = new DataInputStream(clientSocket.getInputStream());
            outputToServer = new DataOutputStream(clientSocket.getOutputStream());
            
            String msg = "";
            while (!"quit".equalsIgnoreCase(msg)){
                msg = inputFromServer.readUTF();
                chatArea.setText(chatArea.getText().trim() + "\nServer: " + msg);
                
            }
                        
        } catch (Exception e) {}
    }

    // Variables declaration - do not modify                     
    private static javax.swing.JTextArea chatArea;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JTextField msgText;
    private javax.swing.JButton send;
    // End of variables declaration                   
}      

                          

這是在我嘗試使用線程之后(消息僅從一個客戶端發送到服務器,反之亦然)。

serverGui1

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
                new ServerGui1().setVisible(true);
                start();
        }
    });
}

public static void start() {
    new Thread(new ServerHandler()).start();
}

private static class ServerHandler implements Runnable {
    @Override
    public void run() {
        try {
            serverSocket = new ServerSocket(2021);
            new Thread(new ClientHandler(serverSocket.accept())).start();
        } catch (Exception e) {
        }
    }
}

private static class ClientHandler implements Runnable {

    private Socket clientSocket;
    private String msg = "";

    public ClientHandler(Socket clientSocket) {
        this.clientSocket = clientSocket;
    }

    @Override
    public void run() {
        try {
            inputFromClient = new DataInputStream(clientSocket.getInputStream());
            outPutToClient = new DataOutputStream(clientSocket.getOutputStream());

            while (!msg.equalsIgnoreCase("quit")) {
                msg = inputFromClient.readUTF();
                chatArea.setText(chatArea.getText().trim() + "\nClient: " + msg);
            }
        } catch (Exception e) {
        }
    }
}

cleintGui1

public static void main(String args[]) {
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
                new ClientGui1().setVisible(true);
                start();
        }
    });
    
}

public static void start() {
    try {
        clientSocket = new Socket("127.8.8.1", 2021);
        outputToServer = new DataOutputStream(clientSocket.getOutputStream());
        new Thread(new Listener()).start();
    } catch (Exception e) {}
}

private static class Listener implements Runnable {
    @Override
    public void run() {
        try {
            inputFromServer = new DataInputStream(clientSocket.getInputStream());
            String msg = "";
            while (!"quit".equalsIgnoreCase(msg)){
                msg = inputFromServer.readUTF();
                chatArea.setText(chatArea.getText().trim() + "\nServer: " + msg);
            }
        } catch (IOException e) {} //Exception e
    }
}

那么,如何修復我的代碼?

在這種情況下,你有一個錯誤,你只會得到一個客戶

String msg = "";
try {
    serverSocket = new ServerSocket(2021);
    clientSocket = serverSocket.accept();

    inputFromClient = new DataInputStream(clientSocket.getInputStream());
    outPutToClient = new DataOutputStream(clientSocket.getOutputStream());
    
    while (!msg.equalsIgnoreCase("quit")){
        msg = inputFromClient.readUTF();
        chatArea.setText(chatArea.getText().trim() + "\nClient: " + msg);
    }
    
} catch (Exception e) {}

因為serverSocket.accept(); 在循環之外。 要修復您的代碼,您應該更改此部分

    boolean EOF = true
    try {
        serverSocket = new ServerSocket(2021);
       
        
        while (EOF){

        clientSocket = serverSocket.accept(); // main thread sleeps until new client is connected, if this stops UI thread then you will have to make one thread for it

        new Thread(new Runnable(){
          run(){

            inputFromClient = new DataInputStream(clientSocket.getInputStream());
            outPutToClient = new DataOutputStream(clientSocket.getOutputStream());
....
    
          }
        }).start()
        }
        
    } catch (Exception e) {}

在我的情況下,為每個客戶創建新線程並不是那么好

但您可以使用 FixedThreadPool 執行器對其進行更新

FixedThreadPool vs CachedThreadPool:兩害相權取其輕

抱歉,我沒有使用編輯器,它可能包含我發布的語法問題,因為您了解如何工作

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM