2017-09-24 87 views
-1

現在我正在製作聊天程序。java套接字(更改另一個類中的布爾值)和數據流

但存在一些問題。

首先,在登錄過程中,當我向服務器發送id/pw時,服務器發送正確或錯誤的(協議3000或3001)。然後,客戶端將獲得協議。和

islogin(boolean)將改變真或假。但是,布爾值不會更改。我不知道爲什麼它沒有改變。有一些代碼。

clientbackground.java

package client; 

import java.io.DataInputStream; 
import java.io.DataOutputStream; 
import java.io.IOException; 
import java.net.Socket; 
import java.util.StringTokenizer; 

import crypto.des; 



public class ClientBackground implements Runnable{ 

    Socket socket; 
    DataInputStream in; 
    private DataOutputStream out; 
    private ClientGui gui; 
    private String msg; 
    String id; 
    private String pass; 
    private boolean islogin; 
    private login_Frame lf; 
    private regform rf; 
    private String info; 
    Thread clientThread; 
    des crypto; 
    String packet=""; 
    String tmp; 
    boolean test = false; 
    int protocol; 


    public final void setGui(ClientGui gui) { 
     this.gui = gui; 
    } 
    public void run() { 
     try { 
      socket = new Socket("192.168.0.11", 7770); 
      System.out.println("connect!."); 
      socket.setTcpNoDelay(true); 
      crypto = new des(); 
      //crypto.SetD(); 
      out = new DataOutputStream(socket.getOutputStream()); 
      in = new DataInputStream(socket.getInputStream()); 
      System.out.println(in.available()); //test 
      System.out.println("okay!"); 
      while (in != null) { 
       packet = in.readUTF(); 
       StringTokenizer st = new StringTokenizer(packet,"/"); 
       tmp = st.nextToken(); 
       msg = st.nextToken(); 
       this.protocol = Integer.parseInt(tmp); 
       System.out.println(this.protocol+"&&&&"); //test 
       switch(this.protocol){ 

       case 3000 :{ 
       System.out.println("success"); 
       test = true; 
       this.lf.gettest(test); 

       } 
       break; 
       case 3001 :{ 
        System.out.println("wrong"); 
        test = false; 
        this.lf.gettest(test); 
       } 
       break; 
       default :{ 
       gui.jta.append(msg); 
       System.out.println(msg); 
       System.out.println(test+"%%"); 
       } 
       break; 
      } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    /*public void loginP() { 
     System.out.println(this.protocol+"&&&&"); 
     switch(this.protocol){ 

     case 3000 :{ 
     System.out.println("success"); 
     test = true; 
     this.lf.gettest(test); 

     } 
     break; 
     case 3001 :{ 
      System.out.println("wrong!"); 
      test = false; 
      this.lf.gettest(test); 
     } 
     break; 
     } 
    }*/ 

    public static void main(String[] args){ 
     ClientBackground clientBackground = new ClientBackground(); 
     Thread clientThread = new Thread(clientBackground); 
     clientThread.setPriority(1); 
     clientThread.start(); 
     clientBackground.lf = new login_Frame(); 
     clientBackground.lf.Clientback(clientBackground); 

    } 
    public void showFrameTest() { 
     this.lf.setVisible(false); 
     this.gui = new ClientGui(); 
     this.gui.Clientback(this); 
    } 
    public void showregfrom() { 
     this.lf.setVisible(false); 
     this.rf = new regform(); 
     this.rf.Clientbackreg(this); 
    } 
    public void relogin_form() { 
     this.rf.dispose(); 
     this.lf.setVisible(true); 
    } 

    public void sendMessage(String msg2) { 
     try { 
      out.writeUTF(msg2); 
      out.flush(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
    public boolean lcheck() { 
     return islogin; 
    } 

    public void setid(String id, String pass) { 
     this.id = id; 
     this.pass = pass; 
    } 
    public String getid() { 
     return id; 
    } 

} 

login_Frame.java

package client; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.DataInputStream; 
import java.security.InvalidKeyException; 
import java.security.NoSuchAlgorithmException; 
import java.security.spec.InvalidKeySpecException; 

import javax.crypto.NoSuchPaddingException; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JOptionPane; 
import javax.swing.JTextField; 

import crypto.des; 



public class login_Frame extends JFrame{ 

    private static final long serialVersionUID = 1L; 
    private String id; 
    private String pass; 
    JButton logb = new JButton("login"); 
    JButton exitb = new JButton("cancel"); 
    JButton regb = new JButton("reg"); 
    JLabel idlb = new JLabel("ID : "); 
    JLabel pwlb = new JLabel("PW : "); 
    JTextField idtb = new JTextField(); 
    JTextField pwtb = new JTextField(); 
    private static ClientBackground client; 
    private DataInputStream in; 
    byte[] CpStr = null; 
    boolean test = false; 
    String packet,tmp; 

    public login_Frame(){ 
     new Thread(client).start(); 
     getContentPane().add(logb); 
     getContentPane().add(exitb); 
     getContentPane().add(regb); 
     getContentPane().add(idlb); 
     getContentPane().add(pwlb); 
     getContentPane().add(idtb); 
     getContentPane().add(pwtb); 

     setLayout(null); 
     setBounds(100, 100, 400, 200); 
     setVisible(true); 
     logb.setBounds(40, 110, 90, 40); 
     exitb.setBounds(150, 110, 90, 40); 
     regb.setBounds(260, 110, 90, 40); 
     idlb.setBounds(20, 10, 50, 40); 
     pwlb.setBounds(20, 60, 50, 40); 
     idtb.setBounds(70, 10, 280, 40); 
     pwtb.setBounds(70, 60, 280, 40); 

     ActionListener confirmListener = new ConfirmListener(); 
     ActionListener exListener = new ExitListener(); 
     ActionListener regListener = new RegListener(); 
     logb.addActionListener(confirmListener); 
     exitb.addActionListener(exListener); 
     regb.addActionListener(regListener); 
     idtb.addActionListener(confirmListener); 
     pwtb.addActionListener(confirmListener); 


    } 
    public String getidtb(){ 
     return idtb.getText(); 
    } 
    public String getpwtb(){ 
     return pwtb.getText(); 
    } 
    private class ConfirmListener implements ActionListener { 
     public void actionPerformed(ActionEvent e){ 

       try { 
        isLoginCheck(); 
        System.out.println(test); //test 
        if(client.test){ 
         System.out.println(client.test+"%%%%"); //test 
         client.showFrameTest(); 
        }     
        else{ 
         JOptionPane.showMessageDialog(null, "wrong!"); 
        } 


       } catch (Exception e1) { 
        // TODO Auto-generated catch block 
        e1.printStackTrace(); 
       } 

     } 
    } 
    private class RegListener implements ActionListener { 
     public void actionPerformed(ActionEvent e){ 
       regbtaction(); 
     } 
    } 
    private class ExitListener implements ActionListener { 
     public void actionPerformed(ActionEvent e){ 
      System.exit(0); 
     } 
    } 
    public void Clientback(ClientBackground client) { 
     this.client = client; 
    } 
    public void isLoginCheck() throws Exception{ 
     id = getidtb(); 
     pass = getpwtb(); 
     new Thread(client).start(); 
     //CpStr = client.crypto.Encrypts(pass); 
     idtb.setText(""); 
     pwtb.setText(""); 
     client.setid(id, pass); 
     client.sendMessage("3004"+"/"+id+"/"+pass); 

    } 
    public void regbtaction() { 
     client.showregfrom(); 
     this.setVisible(false); 
    } 
    public void gettest(boolean test) { 
     this.test = test; 
    } 

} 

我編輯的一些代碼,並添加一些測試代碼來驗證登錄處理。 現在,如果我執行我的程序並單擊登錄按鈕,則會顯示錯誤消息。但是一些測試代碼教給我一些東西。連接!

0 
okay! 
connect!. 
0 
okay! 
false 
3000&&&& 
success 

這是clientBackground的推薦。特別是,3000&&&&success這意味着clientBackground收到了正確的協議。然後,它編輯它的測試布爾(true)。但是這裏有一些問題。我希望當我點擊登錄按鈕時,isLoginCheck將被執行,然後測試布爾必須改變。然而,if(client.test){提前執行。我想要更改處理順序。如何改變順序..?

@洛塔爾plz幫助我。

+0

第一個問題,有什麼優先?我認爲在'login_Frame'中我會點擊登錄按鈕。那麼id/pw將發送服務器。和服務器發送協議。那麼布爾值將會改變。和'login_Frame'登錄按鈕動作的'if(test){'將被執行,不是嗎? – hohodduck

回答

0

您是否看到類似ok等的調試消息?

我能看到一些東西在這裏:

public void sendMessage(String msg2) { 
    try { 
     out.writeUTF(msg2); 
    } catch (IOException e) { 
     e.printStackTrace(); 
    } 
} 

你永遠不會刷新流,所以它可能是你的數據從來沒有得到發送出去。由此你不會收到登錄檢查的結果。

while(in.available()>0) 
{ 
    packet = in.readUTF(); 
    System.out.println(packet+"%%%"); 
} 

這是在解析數據的實際循環之前的while循環。如果您的響應在此循環中發送,則隨後的讀取將丟失。另外,使用in.available不是讀取數據的好方法。 available只返回可以從流中讀取而不被阻塞的字節數。如果網絡連接速度很慢,即使仍然有字節需要讀取,這將返回0

while (in != null) { 
    packet = in.readUTF(); 
    StringTokenizer st = new StringTokenizer(packet,"/"); 
    [...] 

如果要實際解析的數據是前while循環的結果,你用的in.readUTF

while (true) { 
    Receiver receiver = new Receiver(mid_server); 
    receiver.start(); 
} 

此創建線程的成千上萬的重複調用別的東西代替它在幾秒鐘內,當達到允許線程的上限時,最有可能用OutOfMemoryError殺死該應用程序。

+0

您好!你記得我的問題嗎?也許...它沒有解決......我的意思是,我衝我的輸出流,但登錄過程仍然不工作... – hohodduck

+0

@hohodduck我的回答不僅包含刷新輸出流的建議。你是否也修復了其他問題?如果您仍然需要幫助,請編輯您的問題並解釋當前情況,即您當前的代碼是什麼樣的,以及在進行所提出的更改後,新的思路是什麼。 – Lothar

+0

我編輯我的問題! – hohodduck