0

What type of stream can I use to send a request message over a tcp socket to jabber.

I'm writing a string with xml format.

I cant use any libraries. It has to be pure java sockets.

the following is the code which i used. But the response for the second xml request is 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());
        }

this is what i have implemented in c#, it works quite fast too.

 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)
                {
                }
Rohit Vipin Mathews
  • 11,629
  • 15
  • 57
  • 112

1 Answers1

2

You are attaching a 2nd BufferedReader (InputStreamReader (...)) to your stream.

Probably the answer to your second request is being consumed and lost in the first buffer. Try re-using your initial BufferedReader reader; to read the answer to the second message. Remember that XMPP is a single bi-directional stream, so all interaction happens through the same socket throughout the lifetime of your connection.

-- EDIT --

Q: How should the second request be like?

A: Editing your code to give you a starting point (not checked for compilation, just to give you the idea on how to proceed):

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());
    }
}

Notes:

[1] This buffer can be reused across different requests. There's no actual need to recreate it every time this method is called. I left it there to provide you some anchoring with your C# code.

[2] You are checking for EOF in your code. This will potentially not happen in an XMPP connection. It's better to read the characters that are available in the stream until there're no more. Therefore I'm checking on reader.ready() instead of reader.read(...)>-1 See this question for further discussion on EOF: How do I recognize EOF in Java Sockets?

Community
  • 1
  • 1
maasg
  • 37,100
  • 11
  • 88
  • 115