I'm trying to send the player's position (x, y) to the client from the Server. Everything else seems to work, but not these 2 ints. I can send other integers, for example 3456, and it will receive 3456. But these wont work.
Server Java code:
public void sendAccountInformation() throws IOException {
dos.write(player.id);
main.log(player.id);
dos.println(player.username);
main.log(player.username);
dos.write(player.x);
main.log(player.x);
dos.write(player.y);
main.log(player.y);
dos.write(player.mapid);
main.log(player.mapid);
dos.flush();
}
Server output:
0
sdfsdffsd
544
384
0
The above is the correct information that should be sent.
Client Java code:
public void loadAccount() throws IOException {
int id = dis.read();
main.player = new Player(id, main);
main.log(id);
main.player.username = dis.readLine();
main.log(main.player.username);
main.player.x = dis.read();
main.log(main.player.x);
main.player.y = dis.read();
main.log(main.player.y);
main.player.mapid = dis.read();
main.log(main.player.mapid);
}
Client output:
0
sdfsdffsd
63
63
0
As you can see, the two integers (544 and 384) was changed into (63 and 63). But EVERYTHING else sends and is received correctly?
I believe you should try using writeInt() and readInt() to write and read int.
Related
I need to pass an Uint8List to a byte[] array in java over a TCPSocket. There is size mismatch at both ends. PS: I am a beginner in dart.
I have tried socket.add(buf), socket.write(buf), socket.writeAll(buf) but none of them worked
Code in Flutter side (TCP client)
void readVoiceData(Uint8List buf) {
print("Send data size:"+buf.lengthInBytes.toString());
socket.add(buf);
}
OUTPUT: Send data size: 1280
Code Snippet on java side (TCP server)
in = new DataInputStream(clientSocket.getInputStream());
Log.d(TAG, "****Opened InputStream*******");
while (!isInterrupted()) {
if (mTrack != null) {
try {
in.read(bytes);
Log.d(TAG, "Received data size"+bytes.length);
}
}
OUTPUT: Received data size: 1
I am sure the socket connection has been established correctly as I am able to send Strings and Integers flawlessly over them.
This happens because the read() method of the FilterInputStream (DataInput is his son) reads just the next avaliable byte.
Thou, if you want to get the total size of the InputStream, do something like:
size = in.available(); //returns an estimate of number of bytes avaliable on the stream
buf = new byte[size];
realLength= in.read(buf, 0, size);
This code snippet is taken from here.
I would like to send 15 000 caracteres (or 15 000 bytes) by bluetooth with the protocol RFCOMM.
I use this to send data on python :
from pylab import*
from rtlsdr import*
from bluetooth import*
import sys
#configure device
sdr= RtlSdr()
sdr.sample_rate=double(sys.argv[3])
sdr.gain=double(sys.argv[2])
sdr.center_freq=double(sys.argv[1])
NFFT=50
#Bluetooth connection
server_sock=BluetoothSocket(RFCOMM)
server_sock.bind(("",PORT_ANY))
server_sock.listen(1)
port=server_sock.getsockname()[1]
uuid="94f39d29-7d6d-437d-973b-fba39e49d4ee"
client_sock,client_info=server_sock.accept()
while(1):
samples=sdr.read_samples(256*1024)
result=psd(samples,NFFT, Fs=sdr.sample_rate/1e6, Fc=sdr.center_freq*1e6/1e6)
tab_freq=(result[1]/1e6)
value_freq=str(tab_freq)[1:-1]
value_list=[format(float(v), ".10f") for v in value_freq.split()]
value_freq2= "\n".join(value_list)
tab_pxx=result[0]
value_pxx=str(tab_pxx)[1:-1]
client_sock.send(value_freq2+'\n'+'\n'.join(value_pxx.split()))
And this to get data on java :
public void run() {
byte[] buffer = new byte[1048576]; // 20 bits
int bytes;
String strRx = "";
while (running) {
try {
bytes = connectedInputStream.read(buffer);
final String strReceived_freq = new String(buffer,0, bytes);
final String strReceived_pxx = new String(buffer,(bytes/2)+1, bytes);
//final int samples_sdr=new Integer(buffer,0,bytes);
final String strByteCnt = String.valueOf(bytes) + " bytes received.\n";
runOnUiThread(new Runnable(){
#Override
public void run() {
Pxx_value.setText(strReceived_pxx+"\n"); // get data PXX
freq_value.setText(strReceived_freq+"\n"); // get data freq
// plot value
/* for (int i=0; i<nb_points; i++)
{
freq[i]=Double.parseDouble(strReceived_freq);
pxx[i]=Double.parseDouble(strReceived_pxx);
series.appendData(new DataPoint(freq[i],pxx[i]), true,500);
}*/
}});
The problem, After 33 points (NFFT), I can't send more data so my code is rewriting and erase my last data...
How can I fix it ?
Thanks for your help !
I finally found the reason. The Raspberry PI is equiped to Bluetooth 4.1, you can send max 33 bytes for each packet lenght. If you want to get more, you need to upgrade your bluetooth version (Bluetooth 4.2 can send 257 bytes max by packet lenght).
Source : http://www.cypress.com/file/224826/download
I have a very strange situation. I connect my Java software with a device, let´s call it "Black Box" (because I cannot look into it or make traces within it). I am adressing a specific port (5550) and send commands as byte sequences on a socket. As a result, I get an answer from the Black Box on the same socket.
Both my commands and the replies are prefixed in a pre-defined way (according to the API) and have an XOR checksum.
When I run the code from Windows, all is fine: Command 1 gets its Reply 1 and Command 2 gets its Reply 2.
When I run the code from Android (which is actually my target - Windows came into play to track down the error) it gets STRANGE: Command 1 gets its Reply 1 but Command 2 does not. When I play with Command 2 (change the prefix illegally, violate the checksum) the Black Box reacts as expected (with an error reply). But with the correct Command 2 being issued from Android, the Reply is totally mis-formed: Wrong prefix and missing checksum.
In the try to analyse the error I tried WireShark and this shows that on the network interface, the Black Box is sending the RIGHT Reply 2, but evaluating this reply in Java from the socket, it is wrong. How can this be when all is fine for Command/Reply 1???
Strange is, that parts of the expected data are present:
Expected: ff fe e4 04 00 11 00 f1
Received: fd fd fd 04 00 11 00 // byte 8 missing
I am attaching the minimalistic code to force the problem. What could falsify the bytes which I receive? Is there a "raw" access in Java to the socket which could reveal the problem?
I am totally confused so any help would be appreciated:
String address = "192.168.1.10";
int port = 5550;
Socket socket;
OutputStream out;
BufferedReader in;
try {
socket = new Socket(address, port);
out = socket.getOutputStream();
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
// This is "Command 1" which is receiving the right reply
// byte[] allesAn = new byte[] {(byte)0xff, (byte)0xfe, (byte)0x21, (byte)0x81, (byte)0xa0};
// out.write(allesAn);
// This is "Command 2" which will not receive a right reply
byte[] getLokInfo3 = new byte[] {(byte)0xff, (byte)0xfe, (byte)0xe3, (byte)0, (byte)0, (byte)3, (byte)0xe0};
out.write(getLokInfo3);
out.flush();
while (true) {
String received = "";
final int BufSize = 1000;
char[] buffer = new char[BufSize];
int charsRead = 0;
charsRead = in.read(buffer, 0, BufSize);
// Convert to hex presentation
for (int i=0; i < charsRead; i++) {
byte b = (byte)buffer[i];
received += hexByte((b + 256) % 256) + " ";
}
String result = charsRead + ">" + received + "<";
Log.e("X", "Read: " + result);
}
} catch (Exception e) {
Log.e("X", e.getMessage() + "");
}
with
private static String hexByte(int value) {
String s = Integer.toHexString(value);
return s.length() % 2 == 0 ? s : "0" + s;
}
Here is what wireshark says, showing the expected 8 bytes:
I'm trying to work with JSSC.
I built my app according to this link:
https://code.google.com/p/java-simple-serial-connector/wiki/jSSC_examples
My event handler looks like:
static class SerialPortReader implements SerialPortEventListener {
public void serialEvent(SerialPortEvent event) {
if(event.isRXCHAR()){//If data is available
try {
byte buffer[] = serialPort.readBytes();
}
catch (SerialPortException ex) {
System.out.println(ex);
}
}
}
}
}
The problem is that I'm always not getting the incoming data in one piece. (I the message has a length of 100 bytes, Im getting 48 and 52 bytes in 2 separates calls)
- The other side send me messages in different lengths.
- In the ICD Im working with, there is a field which tell us the length of the message. (from byte #10 to byte #13)
- I cant read 14 bytes:
(serialPort.readBytes(14);,
parse the message length and read the rest of the message:
(serialPort.readBytes(messageLength-14);
But if I will do it, I will not have the message in once piece (I will have 2 separates byte[] and I need it in one piece (byte[]) without the work of copy function.
Is it possible ?
When working with Ethernet (SocketChannel) we can read data using ByteBuffer. But with JSSC we cant.
Is there a good alternative to JSSC ?
Thanks
You can't rely on any library to give you all the content you need at once because :
the library dont know how many data you need
the library will give you data as it comes and also depending on buffers, hardware, etc
You must develop your own business logic to handle your packets reception. It will of course depend on how your packets are defined : are they always the same length, are they separated with same ending character, etc.
Here is an example that should work with your system (note you should take this as a start, not a full solution, it doesn't include timeout for example) :
static class SerialPortReader implements SerialPortEventListener
{
private int m_nReceptionPosition = 0;
private boolean m_bReceptionActive = false;
private byte[] m_aReceptionBuffer = new byte[2048];
#Override
public void serialEvent(SerialPortEvent p_oEvent)
{
byte[] aReceiveBuffer = new byte[2048];
int nLength = 0;
int nByte = 0;
switch(p_oEvent.getEventType())
{
case SerialPortEvent.RXCHAR:
try
{
aReceiveBuffer = serialPort.readBytes();
for(nByte = 0;nByte < aReceiveBuffer.length;nByte++)
{
//System.out.print(String.format("%02X ",aReceiveBuffer[nByte]));
m_aReceptionBuffer[m_nReceptionPosition] = aReceiveBuffer[nByte];
// Buffer overflow protection
if(m_nReceptionPosition >= 2047)
{
// Reset for next packet
m_bReceptionActive = false;
m_nReceptionPosition = 0;
}
else if(m_bReceptionActive)
{
m_nReceptionPosition++;
// Receive at least the start of the packet including the length
if(m_nReceptionPosition >= 14)
{
nLength = (short)((short)m_aReceptionBuffer[10] & 0x000000FF);
nLength |= ((short)m_aReceptionBuffer[11] << 8) & 0x0000FF00;
nLength |= ((short)m_aReceptionBuffer[12] << 16) & 0x00FF0000;
nLength |= ((short)m_aReceptionBuffer[13] << 24) & 0xFF000000;
//nLength += ..; // Depending if the length in the packet include ALL bytes from the packet or only the content part
if(m_nReceptionPosition >= nLength)
{
// You received at least all the content
// Reset for next packet
m_bReceptionActive = false;
m_nReceptionPosition = 0;
}
}
}
// Start receiving only if this is a Start Of Header
else if(m_aReceptionBuffer[0] == '\0')
{
m_bReceptionActive = true;
m_nReceptionPosition = 1;
}
}
}
catch(Exception e)
{
e.printStackTrace();
}
break;
default:
break;
}
}
}
After writing data to serial port it need to be flushed. Check the timing and pay attention to the fact that read should occur only after other end has written. read size is just an indication to read system call and is not guaranteed. The data may have arrived and is buffered in serial port hardware buffer but may not have been transferred to operating system buffer hence not to application. Consider using scm library, it flushes data after each write http://www.embeddedunveiled.com/
Try this:
Write your data to the serial port (using serialPort.writeBytes()) and if you are expecting a response, use this:
byte[] getData() throws SerialPortException, IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] b;
try {
while ((b = serialPort.readBytes(1, 100)) != null) {
baos.write(b);
// System.out.println ("Wrote: " + b.length + " bytes");
}
// System.out.println("Returning: " + Arrays.toString(baos.toByteArray()));
} catch (SerialPortTimeoutException ex) {
; //don't want to catch it, it just means there is no more data to read
}
return baos.toByteArray();
}
Do what you want with the returned byte array; in my case I just display it for testing.
I found it works just fine if you read one byte at a time, using a 100ms timeout, and when it does time out, you've read all data in the buffer.
Source: trying to talk to an Epson serial printer using jssc and ESC/POS.
I have an SSL function on my C side that receives only the exact number of bytes sent. Problem is that I'm sending strings & JSON of different byte length's from my servlet.
My Approach: I'm sending the length of each string first then the actual message.
//For Json String (349 bytes)
outputstreamwriter.write(jsonLength);
outputstreamwriter.write(jsonData);
outputstreamwriter.flush();
// For other request strings
final String path = request.getPathInfo();
String all_Users = "GET ALL USERS";
String user_length = Integer.toString(all_Users.length());
String all_Keys = "GET ALL KEYS";
String key_length = Integer.toString(all_Keys.length());
if (path == null || path.endsWith("/users"))
{ outputstreamwriter.write(user_length);
outputstreamwriter.write(all_Users);
}
else if (path.endsWith("/keys")) {
outputstreamwriter.write(key_length);
outputstreamwriter.write(all_Keys);
}
On the C side: I first read the incoming bytes for the incoming string length and then call the function again to expect that message. Now, my Json is 349 while the other requests are 12. These are 3 and 2 bytes respectively.
debug_print("Clearing Buffer\n", NULL);
memset(inBuf, 0, 1024);
ssl_recv_exactly(rs_ssl, inBuf, 2, &ssllog))
lengthValue = atoi(inBuf);
printf("successfully received %d bytes of request:\n<%s>\n", lengthValue, inBuf);
}
if (lengthValue == 13)
{
// Call this function
else if (lengthValue == 12)
{
// call this function
}
Current solution: I'm adding a zero to my 2 byte requests to make them 3 bytes. Any smarter way of doing this?
Going by what Serge and Drew suggested I was to able to do this using Binary method. Here's how I'm sending the string in Binary format:
String user_length = String.format("%9s",
Integer.toBinaryString(all_Users.length()).replace(' ', '0'));