【问题标题】:Why don't the two equal strings match?为什么两个相等的字符串不匹配?
【发布时间】:2018-09-17 12:41:51
【问题描述】:

我想将 来自服务器的响应字符串 进行比较,但在测试这两个字符串时得到错误结果。为什么?

我找到了这个但没有帮助:How do I compare strings in Java?

我尝试了两种方法:

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
String code;
if(Objects.equals((code = in.readLine()), "S")) { //Input string: "S"
    //code
}

 

BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
String code;
if((code = in.readLine()).equals("S")) { //Input string: "S"
    //code
}

代码在这两种情况下都不会运行,因为测试的值为 false

完整代码

服务器端 - C# (Windows)

class ManagePhoneClients
    {
        public void managePhoneClients(object obj)
        {
            Boolean socketalive = true;
            TcpClient tcpClient = (TcpClient)obj;
            StreamReader sr = new StreamReader(tcpClient.GetStream(), Encoding.UTF8);
            StreamWriter sw = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);
            Boolean isPhoneClientConnected = false;
            String user;
            String answer;
            String tl;
            List<string> LC = new List<string>();
            Boolean qss = false;
            Program program = new Program();
            Int32 points = 0;

            ConsoleMethods.writeLine("Thread started for the phone client.", "Info", ConsoleColor.Cyan);

            sw.WriteLine("S");
            sw.Flush();

            while (socketalive == true)
            {
                try
                {
                    if (Program.isMainClientConnected != true || Program.isPowerPointConnected != true)
                    {
                        ConsoleMethods.writeLine("Connection refused because the necessary clients are not connected!", "Error", ConsoleColor.Red);
                        sw.WriteLine("NS");
                        sw.Flush();
                        tcpClient.Close();
                        socketalive = false;
                    }
                    else
                    {
                        sw.WriteLine("LC");
                        sw.Flush();
                    }
                    if (isPhoneClientConnected != true & sr.Peek() != -1)
                    {
                        String rLC = sr.ReadLine();
                        LC.AddRange(rLC.Split('|'));
                        if (LC[1].ToString() == Program.passPhoneClient)
                        {
                            user = LC[0];
                            Program.userNames.Add(user);
                            ConsoleMethods.writeLine("Phone connected from: " + tcpClient.Client.RemoteEndPoint, "Info", ConsoleColor.Cyan);
                            sw.WriteLine("S");
                            sw.Flush();
                            Program.utnr = rLC;
                            isPhoneClientConnected = true;
                        }
                        else
                        {
                            sw.WriteLine("NS");
                            sw.Flush();
                            socketalive = false;
                            ConsoleMethods.writeLine("Phone client disconnected because the password was invalid!", "Error", ConsoleColor.Red);
                        }

                    }
                    switch (sr.ReadLine())
                    {
                        case "CLIENT-EXCEPTION":
                            ConsoleMethods.writeLine("Exception in phone client from: " + tcpClient.Client.RemoteEndPoint + "\n" + sr.ReadLine(), "Client-Error", ConsoleColor.DarkRed);
                            break;
                        case "RECEIVED_POINTS":
                            int point = int.Parse(sr.ReadLine());
                            points += point;
                            ConsoleMethods.writeLine("Phone client succesfully completed a task from: " + tcpClient.Client.RemoteEndPoint + " Point: " + point, "Client-Received Points", ConsoleColor.DarkRed);
                            ConsoleMethods.writeLine("Phone client collected points from: " + tcpClient.Client.RemoteEndPoint + " Points: " + points, "Client-Collected Points", ConsoleColor.DarkRed);
                            break;
                    }

                }
                catch (Exception e)
                {
                    tcpClient.Close();
                    socketalive = false;
                    ConsoleMethods.writeLine(e.Message + e.StackTrace + e.StackTrace, "Error", ConsoleColor.Red);
                }
            }
        }
    }

(这还没有完成!)

客户端 - Java (Android)

   public void login(View v) {
        final Context context = this;
        new Thread(new Runnable() {
            public void run() {
                try {
                    final Socket socket = new Socket("192.168.0.104", 90);
                    BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF8"));
                    PrintWriter out = new PrintWriter(socket.getOutputStream());
                    out.print("P" + "\r\n");
                    out.flush();
                    String code;
                    code = in.readLine();
                    if(code.equals("S")) {
                        if (Objects.equals((code = in.readLine()), "LC")) {
                            out.print(((EditText)findViewById(R.id.username)).getText().toString() + "|" + ((EditText)findViewById(R.id.password)).getText().toString() + "\r\n");
                            out.flush();
                            if(Objects.equals((code = in.readLine()), "S")) {
                                new ServerContact(context).Listener(socket);
                                startActivity(new Intent(Login.this, Waiting.class));
                            } else {
                                throw new Exception("Login failed because the server refused the login request. Server responded with status code: '" + code + "'.");
                            }
                        } else {
                            throw new Exception("Login failed because the server refused the login request. Server responded with status code: '" + code + "'.");
                        }
                    } else {
                        throw new Exception("Login failed because the server refused the login request. Server responded with status code: '" + code + "'.");
                    }
                } catch (Exception e) {
                    new ExceptionWriter(e);
                }
            }
        }).start();
    }

(这还没有完成!)

【问题讨论】:

  • 嗯,结果表明您从readLine 返回的字符串不是 "S"。所以最好的办法是使用 IDE 中内置的调试器来举例 code 变量,看看实际内容是什么。
  • 您可能会收到不可打印的字符。使用调试器检查code 的内容。 (简单地说,打印它的长度)。
  • 你怎么知道code"S"?也许它有一些零宽度字符?将字符串转换为 char 数组并打印每个 char 的整数值。
  • @Sweeper:或者……使用调试器?当您可以打开灯时,无需使用System.out.println 手电筒在黑暗中跌跌撞撞。 :-)
  • 我想我设法解决了这个问题。当我将Ecoding.UTF8替换为new UTF8Encoding(false)时,客户端已成功完成所有测试。

标签: java c# android string if-statement


【解决方案1】:

它对我有用(使用你的第一个案例)。我想我们都已经得出结论,code 实际上并不等于"S",对此感到抱歉。

public class EqualsTest {

   public static void main( String[] args ) throws IOException {
      MyStream socket = new MyStream( new ByteArrayInputStream( "S\n".getBytes() ));

      BufferedReader in = new BufferedReader( new InputStreamReader( socket.getInputStream(), "UTF8" ) );
      String code;
      if( Objects.equals( (code = in.readLine()), "S" ) ) { 
         System.out.println( "true" );
      } else {
         System.out.println( "false" );
      }
   }

   static class MyStream {
      private final InputStream ins;

      public MyStream( InputStream ins ) {
         this.ins = ins;
      }

      public InputStream getInputStream() {
         return ins;
      }

   }
}

输出:

run:
true
BUILD SUCCESSFUL (total time: 0 seconds)

我将添加一些想法来测试code 以进行调试:

     // how to debug
     System.err.println( "code="+code+" length="+code.length() );
     System.err.println( "code bytes="+Arrays.toString( code.getBytes() ) );

【讨论】:

  • 这很有趣......真的不匹配“S”与服务器的“S”。 CODE = [-17, -69, -65, 83]S = [83]
  • 我在您的输入(83)的末尾看到一个“S”,但您显然还有其他垃圾。我想也许你可能没有解码 UTF-8,它可能是其他解码。您的输入中可能还有一个 BOM,尽管我没有仔细检查它的值来确定。
  • 问题是否可能是因为服务器在 C# 中,而客户端在 java (Android) 上运行?双方都有 UTF-8 编码。
  • 所有的 UTF-8 应该是一样的。如果您在 Windows 机器上运行,我认为输入流更有可能是 cp-1252 并包含 BOM,尽管我承认它看起来不像 BOM。
  • @NoelNemeth 或者当然 C# 代码可能有错误/损坏/做错事。尝试从编写它的人那里获得关于该部分代码的确切功能的精确规范。如果您有来源,请将其添加到上面的问题中。
【解决方案2】:

我设法解决了。在服务器端,我必须禁用 BOM。

无 BOM:

StreamWriter sw = new StreamWriter(tcpClient.GetStream(), new UTF8Encoding(false));

带 BOM:

StreamWriter sw = new StreamWriter(tcpClient.GetStream(), Encoding.UTF8);

【讨论】:

  • 如果是解决方案,您应该将此答案标记为正确。
  • @markspace 我知道,但我必须在发布答案后等待 48 小时。
  • 啊,那我错了。对此感到抱歉。
猜你喜欢
  • 2016-03-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-12
  • 1970-01-01
  • 2015-09-25
相关资源
最近更新 更多