java套接字(更改另一个类中的布尔值)和数据流

问题描述:

现在我正在制作聊天程序。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

您是否看到类似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