So, I'm developing an Android app that communicates with server via a socket. Now, the phone will constantly be getting data from a server. The packets will not all be the same size. The first byte of the packet is the type, and then, if applicable, the next four bytes indicate the size. After that, is that many number as floats (4 bytes).
What's the best way to read these in? calling readByte(), readFloat(), readFloat(), etc. or use these Datagram things that I stumbled upon? Explain why. If you want more details to make a better suggestion, please ask.
Thanks,
Sounds like you want to DataInputStream and BuferredInputStream your sockets input stream.
You don't want Datagrams because that is for UDP not sockets.
Then I would use readByte(), optionally readInt() followed by readFloat() etc.
IIUC, if you are talking about JDK datagrams, they are not sockets, they are for UTP communication, which is lighter than TCP but less reliable, and generally used for real time audio/video streaming.
I'd go with DataInputStream/DataOutputStream, and use readByte, readInt, readFloat. This will save you a lot of details about encoding complex numbers on the wire, and also add a (thin) layer of error detection.
If you have java on the other side, it should be no problem at all. If you have C/C++ on the other side, mind that it could (but shouldn't) be using little endian instead of big endian, in which case your numbers (except readByte) will appear scrambled. You can find routines for reading and little endian numbers in java quite easily, but it can cause a bit of a pain attack for the first couple of hours :)
Related
I am developing a java voice chat for a game, I have a problem with the audio mix when several players are talking at the same time. The audio is only sent to nearby players, so I'm storing each user's buffers separately on the client and sending the id along with the voice packet on the server. To listen, I'm going through the list of users and checking the buffers of existing users to reproduce them. However, I have a problem with audio mixing, probably mixing it wrong. How should I mix these audio packages? Audio is 16-bit PCM. When several players are talking together, there is a lot of noise/hiss in these audios, the audio is practically inaudible.
What would be the correct algorithm to apply to this mixer?
Based on my limited experience with mike inputs, my starting point would be to try the following steps:
convert 16-bit bytes to PCM
(consider applying a low-pass filter to the PCM, and possibly volume gain)
add the PCM values together from each line being mixed
convert PCM back to bytes
I can't tell from your description if you are doing step 1 correctly.
A possible place for further research might be at jitsi.org. Their service is written in Java and is open source. It would be interesting to know how they handle this. But it seems to me the most usual thing is that only one line is selected and played at any one time. There may be good reasons for this limitation. But I don't know if it's technical (e.g.,the noise accumulates in a way that drowns out the voices) or if it's just that people talking at the same time create mass confusion quite easily. I supposed there may be echoes/feedback considerations as well. I will be looking forward to seeing what information other people might contribute on this.
I'm designing a system which has two components: A base station running a Java application of my design, and an Arduino running a program also of my design. The Arduino and the base station communicate wirelessly to exchange sensor data. As it stands, I am communicating by sending single bytes back and forth which isn't ideal. A single byte can only represent between 0 and 255 so I am losing sensor sensitivity by scaling from 2048 to 255. To solve this problem, I want to design a network packet. I understand how packets work, but I don't know which format to use for my packet. Is there some standard format I should use or is this kind of thing entirely left up to the programmer?
I presume that you're communicating using UDP? In which case, the format is entirely up to you. You may want to consider inserting a header and footer to bookend the packet allowing you to verify that the entire packet was received. It may also be worth including some way of testing that the packet was received intact, such as including a check-sum of the data but that may be more complicated than your needs require.
Finally, I'd also recommend including an incrementing integer so that you can ignore (or resort) packets that arrived out of order.
so I have a Raspberry Pi that tracks a few temp sensor outputs and controls heaters to meet user defined setpoints. I'm now trying to create an app that talks with the pi so I can see the setpoints and actual temperature reading from my phone. In doing so, I was hoping to use a multicast so that I could eventually expand it to use more than one device. I want to eventually send a few pieces of information including a name for each device and the data values for the various sensors. I was kind of hoping that Java would have something I could send with a datagram packet that contains all of that info. I was thinking something similar to structs in C++ (This is one of my first attempts at Java), but I'm having trouble, since structs don't exist.
I could have a class that is entirely public, but I would then have to send that through the datagram, which seems pretty strange. Is there a better way to do this in Java?
I don't really have code to post, since this is sort of a design issue, but any code samples illustrating possible solutions would be greatly appreciated.
Thanks for your help!
Edit: I should add that while I am writing this for android right now, I intend to do a similar thing on a PC.. I'm not sure how they differ or if they even would in this case, but I figured I'd throw it out there.
Use a DataOutputStream and its primitive-writing methods in conjunction with a ByteArrayOutputStream, and wrap the bytes of he latter in a DatagramPacket. At the receiver, do the converse.
I am working on a university project, where I require communicating Java with Labview, bidirectional, and send and receive data in floating point, in data buffers, because the application in Labview generates data at high speed, but I temporarily store and send when the array has a size of 100.
One of my difucultades is to convert data sent from Labview to Java format and viceversa.
Thanks!!
As far as I can see, you have two options:
Use a text base protocol (XML, JSON, something of your own) and just send the literal "1.3454".
pro: it's probably human readable, which simplifies debugging/ asserting that the correct data is transferred. It is also simpler to have different types of messages.
con: This may mean a loss of precision and definitely means some kind of overhead.
If you just have this one kind of data, you could also extract the bytes of the float and send them, so that the other end can read exactly four bytes and reconstruct the float.
pro: no overhead
con: There might be a problem with endianess. I'm not sure if LabVIEW and Java handle all their data in a specific endian or if it depends on the hardware. You might need to reorder the read bytes before reassembling them back to a float. Also different kinds of messages can get more complicated. On this best read the documentation on the TCP Read VI
You can also mix both approaches: extract the bytes from the float, treat each byte as a character and assemble them as a string, which you put into your text based protocol.
Consider using Labview standard tcp-ip lib or websocket.
I am trying to implement my own remote desktop solution in java. Using sockets and TCP/UDP.
I know I could use VNC or anything else, but its an assignmentwork from school that I want to do.
So for moving the mouse and clicking I could use the Robot class. I have two questions about this:
What about sending the video? I know the Robot class can capture the screen too, so should I just send images in a sequence and display in order at the other side of the connection? Is this the best way to implement remote desktop?
Also should I use TCP or UDP?
I think UDP would be harder to implement since I will have to figure out which image comes after the other.
What you are trying to do will work, but incredibly slow. The images must be compressed before you send them over the net. Before compressing, the number of colors should be reduced. Also, only the portions of the image which have changed since the last update should be sent.
When transferring mouse coordinates an update should only occur if the new mouse position is more than x pixels away from the last position away or a number of y seconds is over. Otherwise you spend so much traffic for the mouse position that there is no room for the images.
UDP will be the best solution here, since it is fastest for video streaming (which is what you are effectively doing).
About 2:
UDP would be much harder, since it's a datagram-based protocol there are limits on how much data you can send at a time; it's not very likely that you are going to be able to fit entire images into single datagrams. So, you're going to have to work with differential/partial updates, which becomes complicated pretty quickly.
TCP, however, is stream-based and only delivers data in-order. If a packet in the middle disappears and needs to be re-sent, all following packets need to wait, even if they've been received by the target machine. This creates lag, which is often very undesirable in interactive applications.
So UDP is probably your best choice, but you can't design it around the assumption that you can send whole images at a time, you need to come up with a way to send just parts of images.
Basically a video is a sequence of images ( frames ) displayed by second. You should send as much as your bandwidth allows you.
On the other hand, there is no point to send the raw image, you should compresss it as much as you can, and definitely consider lose a lot of resolution in the process.
You can take a look at this SO question about image compression if you compress it enough you may have a vivid video.
It will be better if you use Google Protocol buffer or Apache thrift. You will send binary data which will be smaller - by this, your software will work faster.