比较字符串不起作用,空列表不为空
Comparing strings not working, and empty list not empty
我正在开发一个小的服务器-客户端程序。我这里的代码也在不同的程序中运行并且工作正常,但由于某些原因在这个程序中没有。
因此,当用户想要登录时,他们输入用户名和密码,然后将此消息作为 "loginreq user:pass" 发送到服务器套接字。
虽然客户端显然不是问题(我认为)我会为您提供代码:
private static void loginreq(){
String User = null;
String Pass = null;
try {
User = bufferRead.readLine();
WriteOut(ANSI_RESET+"Password: " + ANSI_GREEN);
Pass = bufferRead.readLine();
WriteOut(ANSI_RESET);
} catch (IOException e1) {
e1.printStackTrace();
}
int serverPort = 6880;
String ip = Server;
String data = "loginreq " + User + ":" + Pass;
try{
Socket s = new Socket(ip, serverPort);
DataInputStream input = new DataInputStream( s.getInputStream());
DataOutputStream output = new DataOutputStream( s.getOutputStream());
if(s.isConnected()){
//Step 1 send length
System.out.println("Length"+ data.length());
output.writeInt(data.length());
//Step 2 send length
System.out.println("Writing.......");
output.writeBytes(data); // UTF is a string encoding
//Step 1 read length
int nb = input.readInt();
byte[] digit = new byte[nb];
//Step 2 read byte
for(int i = 0; i < nb; i++){
digit[i] = input.readByte();
}
String st = new String(digit);
System.out.println("Received: "+ st);
} else {
WriteOut("Failed to connect to the server: "+Server+ "No Server");
}
}
catch (UnknownHostException e){
WriteOut("Sock:"+e.getMessage());
}
catch (EOFException e){
WriteOut("EOF:"+e.getMessage());
}
catch (IOException e){
WriteOut("IO:"+e.getMessage());
}
}
以上获取用户名和密码,按照我之前的说明发送。
然后服务器发挥它的魔力(或缺乏)
服务器代码:
//Step 1 read length
int nb = input.readInt();
byte[] digit = new byte[nb];
//Step 2 read byte
String st =null;
for(int i = 0; i < nb; i++){
digit[i] = input.readByte();
st = new String(digit);
}
ServerOut("Recieved : " + ANSI_CYAN +
clientSocket.getInetAddress() + ANSI_RESET + " - " + st);
if (st.startsWith("loginreq ")){ //login attempt
ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() +" Proccessing login request from: " + clientSocket.getInetAddress());
try(BufferedReader br = new BufferedReader(new FileReader("users.txt"))) {
st = st.replaceFirst("loginreq ", "");
for(String line; (line = br.readLine()) != null; ) {
if(st.equals(line)){
String[] userDat = st.split(":");
boolean duplicate = false;
if(!connected.isEmpty()){
for(User u : connected){
if (u.getUsername().equals(userDat[0])){
duplicate = true;
break;
} else {
}
}
}
if (duplicate){
ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() +" User rejected (duplicate) " + userDat[0] + " : " + clientSocket.getInetAddress());
clientReturn("User was already logged in!");
} else {
User user = new User(clientSocket.getInetAddress().toString(), userDat[0], (int) time);
connected.add(user);
ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() + " User: '" + userDat[0] + "' logged in with ip: " + clientSocket.getInetAddress());
clientReturn("Login accepted!");
}
break;
}
}
} catch (Exception ex){
clientReturn("Server ran into an error!");
ex.printStackTrace();
}
}
这会读取客户端输入,如果它以 "loginreq " 开头,则删除它并分隔字符串,以便 userDat[0] 是用户名,userDat[1] 是密码。至此,它已经验证了用户存在。然后,如果有用户连接(我刚刚启动服务器,所以没有任何用户),它会发现同一用户是否已经登录,出于某种原因,这似乎 return 正确。然后它 return 向客户端发送用户已经登录的信息。这不仅是一个问题,而且虽然使用 ServerOut 的初始启动代码正确地打印到控制台,但现在它在一个新线程中似乎根本不打印。我怀疑这可能是因为我使用的是 Jansi 控制台而不是 IDK。
抱歉这么长 post,但感谢您的容忍!
问题似乎是 connected
列表包含了不应包含任何条目的条目。
你需要弄清楚这是怎么发生的。查看创建列表对象的代码,并检查您是否没有使用错误的内容预先填充它。列表不会神奇地凭空获得条目1。如果它是非空的,那么你的代码已经把条目放在那里......某处,不知何故。
我还会添加一些日志记录以查看 connected
包含什么,以及 "duplicate checking" 代码之前的 userDat[0]
是什么。
最后,既然你提到这段代码是多线程的:
- 检查是否只有一个
connected
并且所有线程共享它。
- 检查您是否正确同步。
(我怀疑你没有正确同步。这不能直接解释你所描述的行为...... connected
在任何人尝试登录之前非空......但它是有责任的导致其他问题。)
如果这没有帮助,那么您将需要提供一个 MCVE 以便我们可以 >>运行<< 您的代码找出这里实际发生的事情。
1 - 虽然理论上可行,但我认为 class 库或 JVM 中存在错误的可能性不大。
我正在开发一个小的服务器-客户端程序。我这里的代码也在不同的程序中运行并且工作正常,但由于某些原因在这个程序中没有。
因此,当用户想要登录时,他们输入用户名和密码,然后将此消息作为 "loginreq user:pass" 发送到服务器套接字。
虽然客户端显然不是问题(我认为)我会为您提供代码:
private static void loginreq(){
String User = null;
String Pass = null;
try {
User = bufferRead.readLine();
WriteOut(ANSI_RESET+"Password: " + ANSI_GREEN);
Pass = bufferRead.readLine();
WriteOut(ANSI_RESET);
} catch (IOException e1) {
e1.printStackTrace();
}
int serverPort = 6880;
String ip = Server;
String data = "loginreq " + User + ":" + Pass;
try{
Socket s = new Socket(ip, serverPort);
DataInputStream input = new DataInputStream( s.getInputStream());
DataOutputStream output = new DataOutputStream( s.getOutputStream());
if(s.isConnected()){
//Step 1 send length
System.out.println("Length"+ data.length());
output.writeInt(data.length());
//Step 2 send length
System.out.println("Writing.......");
output.writeBytes(data); // UTF is a string encoding
//Step 1 read length
int nb = input.readInt();
byte[] digit = new byte[nb];
//Step 2 read byte
for(int i = 0; i < nb; i++){
digit[i] = input.readByte();
}
String st = new String(digit);
System.out.println("Received: "+ st);
} else {
WriteOut("Failed to connect to the server: "+Server+ "No Server");
}
}
catch (UnknownHostException e){
WriteOut("Sock:"+e.getMessage());
}
catch (EOFException e){
WriteOut("EOF:"+e.getMessage());
}
catch (IOException e){
WriteOut("IO:"+e.getMessage());
}
}
以上获取用户名和密码,按照我之前的说明发送。
然后服务器发挥它的魔力(或缺乏) 服务器代码:
//Step 1 read length
int nb = input.readInt();
byte[] digit = new byte[nb];
//Step 2 read byte
String st =null;
for(int i = 0; i < nb; i++){
digit[i] = input.readByte();
st = new String(digit);
}
ServerOut("Recieved : " + ANSI_CYAN +
clientSocket.getInetAddress() + ANSI_RESET + " - " + st);
if (st.startsWith("loginreq ")){ //login attempt
ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() +" Proccessing login request from: " + clientSocket.getInetAddress());
try(BufferedReader br = new BufferedReader(new FileReader("users.txt"))) {
st = st.replaceFirst("loginreq ", "");
for(String line; (line = br.readLine()) != null; ) {
if(st.equals(line)){
String[] userDat = st.split(":");
boolean duplicate = false;
if(!connected.isEmpty()){
for(User u : connected){
if (u.getUsername().equals(userDat[0])){
duplicate = true;
break;
} else {
}
}
}
if (duplicate){
ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() +" User rejected (duplicate) " + userDat[0] + " : " + clientSocket.getInetAddress());
clientReturn("User was already logged in!");
} else {
User user = new User(clientSocket.getInetAddress().toString(), userDat[0], (int) time);
connected.add(user);
ServerOut("[" + Server.getTimeNow() + "] "+getThreadInfoString() + " User: '" + userDat[0] + "' logged in with ip: " + clientSocket.getInetAddress());
clientReturn("Login accepted!");
}
break;
}
}
} catch (Exception ex){
clientReturn("Server ran into an error!");
ex.printStackTrace();
}
}
这会读取客户端输入,如果它以 "loginreq " 开头,则删除它并分隔字符串,以便 userDat[0] 是用户名,userDat[1] 是密码。至此,它已经验证了用户存在。然后,如果有用户连接(我刚刚启动服务器,所以没有任何用户),它会发现同一用户是否已经登录,出于某种原因,这似乎 return 正确。然后它 return 向客户端发送用户已经登录的信息。这不仅是一个问题,而且虽然使用 ServerOut 的初始启动代码正确地打印到控制台,但现在它在一个新线程中似乎根本不打印。我怀疑这可能是因为我使用的是 Jansi 控制台而不是 IDK。
抱歉这么长 post,但感谢您的容忍!
问题似乎是 connected
列表包含了不应包含任何条目的条目。
你需要弄清楚这是怎么发生的。查看创建列表对象的代码,并检查您是否没有使用错误的内容预先填充它。列表不会神奇地凭空获得条目1。如果它是非空的,那么你的代码已经把条目放在那里......某处,不知何故。
我还会添加一些日志记录以查看 connected
包含什么,以及 "duplicate checking" 代码之前的 userDat[0]
是什么。
最后,既然你提到这段代码是多线程的:
- 检查是否只有一个
connected
并且所有线程共享它。 - 检查您是否正确同步。
(我怀疑你没有正确同步。这不能直接解释你所描述的行为...... connected
在任何人尝试登录之前非空......但它是有责任的导致其他问题。)
如果这没有帮助,那么您将需要提供一个 MCVE 以便我们可以 >>运行<< 您的代码找出这里实际发生的事情。
1 - 虽然理论上可行,但我认为 class 库或 JVM 中存在错误的可能性不大。