现在我正在制作聊天节目。
但是有一些问题。
首先,在登录过程中,当我将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){
会提前执行。我想要改变处理顺序。如何更改订单..?
@Lothar PLZ帮助我。
答案 0 :(得分: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终止此应用程序。