I am trying to read strings from a Bluetooth SPP server into my Android client. The server works fine, and sends the strings to the client as is evidenced in the Logcat.The LogCat indicates that bytes are read in from the btSocket. However, my attempt to read from the socket and display to the strings to the TextView has been futile. Here is the Android client and here is the logcat to evidence that the server works fine. Some Android & java guru to kindly assist. Thanks.
Try something like this :
byte[] buffer = new byte[1024];
int bytes;
inFromServer = nmeaServerSocket.getInputStream();
bytes = inFromServer.read(buffer);
String readMessage = new String(buffer, 0, bytes);
Log.d(TAG, "Message :: "+readMessage);
Hope it helps you.
Thanks.
Related
I'am really sorry if this is a duplicate question but I tried many answers in other threads and none of them worked for me.
I'am trying to send an ISO8583 message to a remote server through an SSLSocket using the TLSv1.2 protocol, I configured the certificate with the Keystore and attempted to send a sample ISO8583 message : 08002220010000800000900000011312115000000180105000003
0800: MTI
2220010000800000: Binary Hex Encoded Bitmap (Only fields 3, 7, 11, 24, 41 are present)
900000: Process code
0113121150: Transmission Date&Time
000001: STAN
801: Function code
05000003: Terminal ID
I then converted the message to an array of bytes and sent it with the socket OutputStream but no response came from the server and it is freezing when attempting to read the InputStream.
For the purpose of this question, I chose to test a manually-set sample message and not use any packaging method.
I'm very new to the ISO8583 so I don't exactly know what I'm doing wrong.
Here is the code I tried so far and thank you so much to who ever that will try to help me.
Thread thread = new Thread(() -> {
try {
X509TrustManager[] tmm;
KeyStore ks = KeyStore.getInstance("BKS");
InputStream is = getResources().openRawResource(R.raw.tunrootca2);
ks.load(is, KEY_PASSWORD.toCharArray());
tmm=tm(ks);
SSLContext ctx = SSLContext.getInstance("TLSv1.2");
ctx.init(null, tmm, null);
SSLSocketFactory SocketFactory = ctx.getSocketFactory();
SSLSocket socket = (SSLSocket) SocketFactory
.createSocket(REMOTE_ENDPOINT, REMOTE_ENDPOINT_PORT);
String sampleMessage = "080022200100008000009000000113120000000180105000003";
byte[] bytesMessage = sampleMessage.getBytes(StandardCharsets.UTF_16LE);
byte[] bytes = packData(bytesMessage);
OutputStream out = socket.getOutputStream();
out.write(bytes);
byte[] buffer = new byte[256];
InputStream in = socket.getInputStream();
int read;
while((read = in.read(buffer)) != -1) {
String output = new String(buffer, 0, read);
Log.v("SOCKET_OUTPUT", output);
}
} catch (Exception e) {
e.printStackTrace();
}
});
thread.start();
});
PackData Function
static byte[] packData(byte[] data) {
int len = data.length;
byte buf[] = new byte[len + 2];
buf[0] = (byte) (len >> 8 & 255);
buf[1] = (byte) (len & 255);
System.arraycopy(data, 0, buf, 2, len);
return buf;
}
Settuing up socket communication can be tricky. If possible, I'd advise using WebSockets for communication, as they're already set up with how the communications protocols connect.
But if you are going to stick with plain sockets:
After your write call, call flush();
out.write(bytes);
out.flush();
If 1 didn't work, things get trickier. Since you don't control the server side part of this, it's hard to know what you need to send them in order to get them to send you something back. You might try sending a newline character. But otherwise, there's a mismatch between what you are sending and what the server on the other end is expecting
--- Edit ---
I looked up ISO 8583 and have a better idea of what you are trying to do. You can ignore my previous suggestion on using WebServer sockets.
You are missing the basics. You can't build ISO messages using string concatenation. You have to set correct bitmaps for those enable fields. Maybe try to follow the below sample. It will guide you with the basics.
https://kodejava.org/how-do-i-pack-an-iso-8583-message/
Your code looks ok. What sort of backend are you connecting to? 8583 is a bit like xml, it's a format description, but every processor uses it to build their own specific protocol from it, so you really need to ask the vendor you are connecting to for protocol documentation.
Some things that may be the matter:
flush the OutputStream when you are done writing, the message may still be hanging in your OS buffer
check the vendor documentation whether you need some sort of framing you may need to append a checksum to the message or ...
you may need to prepend a length header to the message. 8583 was originally built on top of relay protocols where the transport handled message length. A lot of parsers haven't caught up yet with the transition to TCP/IP :)
InputStream in = socket.getInputStream();
byte[] content = new byte[2048];
int received = in.read(content, 0, content.length);
System.out.println(received);
Using this code, I would like to know how I retrieve only the number of bytes that the server sends me.
I was told to use a loop using a Buffer, but as I am new to this area, I didn't quite understand what it means, could someone give me a hand?
You are storing the number of bytes that the server sends you in the received variable. If you want to convert the data that the server sent into a string for debugging purposes, this is how you can do it:
int received = in.read(content, 0, content.length);
String messageFromServer = new String(content, 0, received);
Note that in general you need to call read multiple times in order to receive all the data from the server, just like with any InputStream. You can find tutorials on using Input and OutputStreams here:
https://docs.oracle.com/javase/tutorial/essential/io/bytestreams.html - specific example for reading and writing files, but sockets are no different.
http://tutorials.jenkov.com/java-io/inputstream.html - more general and thorough tutorial
I am testing a java code to issue AT Commands to the Modem at the designated port. I was able to successfully make Socket connection to the Modem's default gateway IP and AT Command port and write AT commands to that socket. (something like below)
Socket socket = new Socket(address, port);
socket.setKeepAlive(true);
...
String command = "AT\r\n";
...
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
out.write(commandBytes, 0, commandBytes.length);
out.flush();
And try to read the response from the socket as below
BufferedInputStream in = new BufferedInputStream(socket.getInputStream());
byte[] byteArray = new byte[1024];
int count = in.read(byteArray, 0, byteArray.length);
System.out.println("Response Received: " + new String(byteArray, StandardCharsets.US_ASCII));
The problem is, I am getting bad characters (like ??) as the response. I am expecting the output as "OK". When I issue the same command from the command prompt of the same PC where I am running this code, I am getting the response in proper English. I am assuming (mostly true) that the modem might be using a different language like C, C++ and their byte rage is different from the byte range of Java. But if this is the case, I am not sure how to fix it. Need help.
Things that I have already tried:
Printed the bytes as retrieved and found that these are of negative byte values (like -1, -3, -5 etc)
Verified the default of charset of the modem and if found to be ISO-8859-1 and tried using the same in my code (both write and read) still getting similar bad characters only
Tried reading as characters using BufferredReader* classed, but nothing is getting received at the response
My question in short, how to read the binary(byte array) data received as response from Modem for the given AT commands issued from Java Socket Connection?
Any help in this regard is highly appreciated.
I am trying to send xml to an IP. I am doing that with following code:
String sMessage = "<SERVER><CONNECT><IP>192.168.10.14</IP><CLIENT_ID>123</CLIENT_ID></CONNECT></SERVER>";
Socket socket = new Socket("192.168.252.148", 34543);
System.out.println("socket connected---: "+socket.isConnected());
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
InputStream in = socket.getInputStream();
out.println(sMessage);
byte[] buffer = new byte[in.available()];
in.read(buffer);
String rMsg = new String(buffer);
System.out.println("rMsg: "+rMsg);
out.close();
in.close();
socket.close();
rMsg is always empty. socket connection is true. Why am i not getting response back. I tried to change InputStream to BufferedInputStream but it did not help. Any idea to solve this problem by either fixing this code or by having new idea? Thanks in advance.
I'm afraid I don't really understand what you are trying to do. Your sending an XML file to an address, fair enough, but why are you automatically assuming the destination knows how to understand and create an XML formatted reply? What is the server-side implementation?
If there is such an implementation and you are not receiving data, then there must be a problem on that end, could you post code from it?
What should the server send you back? The thing is that you send an XML to the server and want to receive input at the same time from the server. But the response from the server may take some time. But I guess at this point your inputstream is closed or you are not listening to that any more. One simple solution to check that will be to put everythin in a while loop so you will see if your server answers (a bit later)... you also can listen to the NIC of your server with wireshark. Perhaps your server doesn't send anything?
I have strange problem with receiving data from socket.
On client im using air socket. On server java netty.
Im writing to socket simple packets: int numPacket, int textLength, utf8String text. And read on client.
//server
buffer.writeInt( packetId );
ChannelBuffer ch = ChannelBuffers.copiedBuffer( text, CharsetUtil.UTF_8);
buffer.writeInt( text.length() );
buffer.writeBytes(ch);
//client
packetId = socket.readInt()
packetLen = socket.readInt()
text = socket.readUtfBytes(packetLen)
Sometimes one packets() doesnt receives by client, but server was send there, and tcpdump show that packet was send. If server send new packet, client read previous packet, and doesn't receivs new packet - and it's works like queue that im don't need.
p.s sorry for bad english -_-
Looks like client maybe waiting for some byte \n,\u etc to know the end of frame. I had similar problem with flash because the client was expecting a null byte at the end of the the transmission.
You could try to add the following sort of encoder as the last encoder in your pipeline and give it a try. The relevant code for handling nul byte is shown below.
ChannelBuffer nulBuffer = ChannelBuffers.wrappedBuffer(new byte[] { 0 });
ChannelBuffer buffer = ChannelBuffers.wrappedBuffer((ChannelBuffer)msg,nulBuffer);
Try using flush() on your buffer after each or all three