【问题标题】:Java connection to Jabber with only Sockets仅使用套接字与 Jabber 的 Java 连接
【发布时间】:2012-03-19 11:38:38
【问题描述】:

我可以使用什么类型的流通过 tcp 套接字向 jabber 发送请求消息。

我正在写一个xml格式的字符串。

我不能使用任何库。它必须是纯 Java 套接字

以下是我使用的代码。但是第二个xml请求的响应是null

 try {


            Socket s = new Socket("195.211.49.6", 5222);

            PrintWriter out = new PrintWriter(s.getOutputStream());
            out.println("<stream:stream to='nimbuzz.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");

            out.flush();

            BufferedReader reader = new BufferedReader(new InputStreamReader(s
                    .getInputStream()));

            String line;
            while ((line = reader.readLine()) != null) {
                System.out.println(line);

            }

            out.println("<iq type='set' xml:lang='en' id='terms' to='nimbuzz.com'><query xmlns='jabber:iq:auth'><username>username</username><password>password</password><resource>resource</resource></query></iq>");
           out.flush();
            reader = new BufferedReader(new InputStreamReader(s
                    .getInputStream()));
            while ((line = reader.readLine()) != null) {
                System.out.println(line);

            }
            s.close();

        }  catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }

这是我在 c# 中实现的,它的运行速度也非常快。

 Socket m_socWorker;
                try
            {
                m_socWorker = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.IP);
                string ipString = "195.211.49.6";
                string str2 = "5222";
                int port = Convert.ToInt16(str2, 10);
                IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse(ipString), port);
                m_socWorker.Connect(remoteEP);

            string page=string.Empty, page1=string.Empty, page2=string.Empty;
            string s = "<stream:stream to='nimbuzz.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>";
                    byte[] bytes = Encoding.UTF8.GetBytes(s);
                    byte[] buffer = new byte[0x4b38];
                     m_socWorker.Send(bytes, bytes.Length, SocketFlags.None);
                    int count = 0;
                    count =  m_socWorker.Receive(buffer, buffer.Length, SocketFlags.None);
                     page =  page + Encoding.ASCII.GetString(buffer, 0, count);
                    byte[] buffer3 = new byte[0x4b38];
                    int num2 = 0;
                    num2 =  m_socWorker.Receive(buffer3, buffer3.Length, SocketFlags.None);
                     page1 =  page1 + Encoding.ASCII.GetString(buffer3, 0, num2);
                     if (page1.Replace("\"", "'").IndexOf("<stream:features><starttls xmlns='urn:ietf:params:xml:ns:xmpp-tls'/><mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'><mechanism>PLAIN</mechanism><mechanism>PLAIN TEXT</mechanism></mechanisms><register xmlns='http://jabber.org/features/iq-register'/></stream:features>", 0) != 0)
                     {
                         string str3 = "<iq type='set' xml:lang='en' id='Nimbuzz_Login' to='nimbuzz.com'><query xmlns='jabber:iq:auth'><username>username</username><password>password</password><resource>resource</resource></query></iq>";
                         byte[] buffer4 = new byte[0x30d40];
                         buffer4 = Encoding.UTF8.GetBytes(str3);
                         byte[] buffer5 = new byte[0x4b38];
                         m_socWorker.Send(buffer4, buffer4.Length, SocketFlags.None);
                         int num3 = 0;
                         num3 = m_socWorker.Receive(buffer5, buffer5.Length, SocketFlags.None);
                         page2 = Encoding.ASCII.GetString(buffer5, 0, num3);
                         string str4 = page2.Replace("\"", "'");
                         int num4 = 1;
                     }
            }
                catch (SocketException)
                {

                }
                catch (Exception)
                {
                }

【问题讨论】:

    标签: java sockets


    【解决方案1】:

    您正在将第二个BufferedReader (InputStreamReader (...)) 附加到您的信息流中。

    您的第二个请求的答案可能正在第一个缓冲区中被消耗和丢失。 尝试重新使用您最初的BufferedReader reader; 来阅读第二条消息的答案。请记住,XMPP 是一个单一的双向流,因此在连接的整个生命周期内所有交互都通过同一个套接字进行。

    -- 编辑--

    问:第二个请求应该是怎样的?

    A:编辑您的代码为您提供一个起点(未检查编译,只是为您提供如何继续的想法):

    private static final int BUFFER_SIZE = 1024;
    
    // Encapsulate the read process
    private String readData(Reader reader) throws IOException {
        StringBuilder result = new StringBuilder(); 
        char[] buffer = new char[BUFFER_SIZE];  // [note1]
        while (reader.ready()) { // [note2]
            int charsRead = reader.read(buffer,0,BUFFER_SIZE-1));
            if (charsRead > 0) {
                result.append(buffer,0,charsRead);
            }
        }
        return result.toString();
    }
    
    public void readStuff() { 
        try {
            Socket s = new Socket("195.211.49.6", 5222);
    
            PrintWriter out = new PrintWriter(s.getOutputStream());
            BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(s.getInputStream()));
            out.println("<stream:stream to='nimbuzz.com' xmlns='jabber:client' xmlns:stream='http://etherx.jabber.org/streams' version='1.0'>");
            out.flush();
    
            // Read out the data and print it to the console
            System.out.println(readData(bufferedReader));
    
            // Second request over the same socket
            out.println("<iq type='set' xml:lang='en' id='terms' to='nimbuzz.com'><query xmlns='jabber:iq:auth'><username>username</username><password>password</password><resource>resource</resource></query></iq>");
            out.flush();
    
            // Read out the answer for the second result
            System.out.println(readData(bufferedReader));
    
    
        } catch (UnknownHostException e) {
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
             e.printStackTrace();
        } catch (Exception e) {
            System.out.println(e.getLocalizedMessage());
        }
    }
    

    注意事项:

    [1] 这个缓冲区可以在不同的请求中重复使用。每次调用此方法时实际上不需要重新创建它。我把它留在那里是为了给你的 C# 代码提供一些锚定。

    [2] 您正在检查代码中的 EOF。这可能不会在 XMPP 连接中发生。最好读取流中可用的字符,直到没有更多字符为止。因此,我正在检查 reader.ready() 而不是 reader.read(...)>-1 有关 EOF 的进一步讨论,请参阅此问题:How do I recognize EOF in Java Sockets?

    【讨论】:

    • 第二个请求应该怎么样?
    • @Rohit 我已修改您的代码作为对此答案的编辑。我希望这会有所帮助。
    • 这段代码是用于 Java 的吧?我不是 java 程序员,但出于某种原因,我必须在 java 中实现我在 c# 中所做的功能
    • @Rohit 只是把它放到一个类中,加点水混合 :-)
    • 谢谢!!我无法从System.out 线:-X
    猜你喜欢
    • 2010-09-16
    • 1970-01-01
    • 2013-02-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多