我可以使用哪种类型的流通过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)
{
}
答案 0 :(得分:2)
您正在将第二个BufferedReader (InputStreamReader (...))
附加到您的信息流中。
第二个请求的答案可能是在第一个缓冲区中消耗和丢失。
尝试重新使用您的初始BufferedReader reader;
来阅读第二条消息的答案。请记住,XMPP是一个单向双向流,因此所有交互都会在连接的整个生命周期内通过同一个套接字发生。
- 编辑 -
问:第二个请求怎么样?
答:编辑你的代码给你一个起点(没有检查编译,只是为了让你知道如何继续):
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(...)&gt; -1 有关EOF的进一步讨论,请参阅此问题:How do I recognize EOF in Java Sockets?