Get InputStream From a Socket - java

I want to stream and audio with SIP Connection in java application(SE).I connected with the server and got 200 OK messages.I want to receive data sent by the server. I created a SOCKET and got an InputStream. Here is how I do it. 123.456.789.1 is the my ip address and 1234 is which my application listening port.
Socket socket=new Socket("123.456.789.1",1234);
InputStream in=socket.getInputStream();
System.out.println("inputSream available :"+in.available());
But in.available() is always 0 .
But if I get the Object content=response.getContent();
ByteArrayOutputStream bos = new ByteArrayOutputStream();
ObjectOutput out = new ObjectOutputStream(bos);
out.writeObject(content);
byte[] contentBytes = bos.toByteArray();
the lenght of contenBytes equals to the response content length.But when I try to get inputStream and Play ,like following
InputStream pp=new ByteArrayInputStream(b);
AudioStream as = new AudioStream(pp);
AudioData data = as.getData();
ContinuousAudioDataStream cas = new ContinuousAudioDataStream (data);
An Exception throws;java.io.IOException: could not create audio stream from input stream
Then I tried to read the inputstream in.read() then when read some bytes,and IOException was thrown.
Q1. How can I solve and get InputStream from the socket?
Q2. how to get an inputStream to play the audio?
or let me know where the problem is and how to solve it.
UPDATED: Thank you all who showed a fault in.availabe();
Then I changed the code.
ByteArrayOutputStream ou=new ByteArrayOutputStream();
int i=0;
System.out.println("Before while");
while((i=in.read())!=-1){
ou.write(i);
System.out.println("Wrote :"+i);
}
Unfortunately the application doesn't go further.That means only Before while is printed.Application just shows running(I use netbeans IDE).I don't why.Any clarification?

When you use getContent you get some kind of object wrapping the content. Then using an ObjectOutputStream you write the Java representation of that object, not the actual bytes of the original data.
You should be able to do
AudioStream as = new AudioStream(in);
AudioData data = as.getData();
ContinuousAudioDataStream cas = new ContinuousAudioDataStream (data);
or if you do want to buffer the data
int chunkSize;
byte[] chunk = new byte[2048];
ByteArrayOutputStream outBuffer = new ByteArrayOutputStream();
while ( ( chunkSize = in.read(chunk) ) != -1) {
outBuffer.write(chunk, 0, chunkSize);
}
ByteArrayInputStream inBuffer = new ByteArrayInputStream(outBuffer.toByteArray());
AudioStream as = new AudioStream(inBuffer);
AudioData data = as.getData();
ContinuousAudioDataStream cas = new ContinuousAudioDataStream (data);
available() show how many bytes can be guaranteed read before blocking. It might always return 0.

available() is the number of bytes which can be read with out performing a blocking call to the OS. If you want to know how much data is available you should try to read it and see how much you get.

Related

Inconsistent byte array read when sent from PC to PC and from PC to Android

I have a Server application on my PC which reads a jpg file and sends it through a socket to the android device. The problem is that when android device receives a byte array, it can't be converted to bitmap. I created a PC application to receive that same array and the data received is different than on the android even though I am using the same code to receive it.
Hence my assumption is that I somehow need to read it differently on android.
PC Java Server
ServerSocket serverSocket = new ServerSocket(PORT);
Socket clientSocket = serverSocket.accept();
BufferedImage image = ImageIO.read(new File("D:\\test1\\test.jpg"));
ByteArrayOutputStream byteArrayoutputStream = new ByteArrayOutputStream();
ImageIO.write(image, "jpg", byteArrayoutputStream);
OutputStream outputStream = clientSocket.getOutputStream();
byte[] size = ByteBuffer.allocate(4).putInt(byteArrayoutputStream.size()).array();
outputStream.write(size);
outputStream.write(byteArrayoutputStream.toByteArray());
outputStream.flush();
Thread.sleep((long)5000);
clientSocket.close();
Android receiver
DataInputStream inputStream = new DataInputStream(serverSocket.getInputStream());
byte[] sizeAr = new byte[4];
inputStream.read(sizeAr);
int size = ByteBuffer.wrap(sizeAr).asIntBuffer().get();
byte[] imageAr = new byte[size];
inputStream.read(imageAr);
System.out.println(imageAr.toString());
bMap = BitmapFactory.decodeByteArray(imageAr, 0, imageAr.length);//this returns null
You probably are not receiving the whole thing,
Instead:
inputStream.read(imageAr);
try:
inputStream.read(imageAr, 0, size);
the second form will wait until size bytes are received.
ADDED
Also do the same on the first read()
instead: inputStream.read(sizeAr); try inputStream.read(sizeAr, 0, 4);
Also get and check inputStream.read() return values, it says how many bytes were really read.

reading bytes file offline using sockets - Java

I have a byte file that contains tcp packets. I want to use sockets to read those packets.
so is it possible to use Sockets to read this file without connection ?
FileInputStream mInStream = new FileInputStream("file path").
byte[] buffer = new byte[1024];
// Keep listening to the InputStream
while (true) {
try {
bytes = mInStream.read(buffer, 0, buffer.length);
}catch {}
}
No, but you can use a FileInputStream and read bytes from the files like the following snippet:
byte[] buffer = new byte[1024];
FileInputStream fis = new FileInputStream("path_to_file").
while((fis.read(buffer) != -1)
// do something with the bytes readed

Strange behavior of java streaming

I've the necessity to share a streaming of data between two instances as below:
// get EClasses which should be connected
final uk.man.xman.xcore.Parameter source = getParameter(sourceAnchor);
final uk.man.xman.xcore.Parameter target = getParameter(targetAnchor);
// Set data channels
//Output stream
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
DataOutputStream dataOutputStream = new DataOutputStream(new BufferedOutputStream(outputStream));
source.setOutputStream(dataOutputStream);
//Input stream
DataInputStream inpuDataStream = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray())));
target.setInputStream(inpuDataStream);
Everything works ok if I write, during those lines of code. Strangely, when I need to use the data channel to write something in another class, like here:
DataOutputStream dataOutputStream = (DataOutputStream) inputParameter.getOutputStream();
System.out.println("WRITE:" + attributes.getValue("value"));
dataOutputStream.writeUTF(attributes.getValue("value"));
dataOutputStream.flush();
I am not able to read, and I really do not know why. Am I missing something?
Thanks for your time
Not sure if that's what you're asking, but you're creating an InputStream that reads from an empty byte array. That doesn't make much sense:
// create an Output stream that will write in memory
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
...
// transform what has been written to the output stream into a byte array.
// Since othing has been written yet, outputStream.toByteArray() returns
// an empty array
DataInputStream inpuDataStream = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(outputStream.toByteArray())));

Receive byte[] using ByteArrayInputStream from a socket

Here is the code but got error:
bin = new ByteArrayInputStream(socket.getInputStream());
Is it possible to receive byte[] using ByteArrayInputStream from a socket?
No. You use ByteArrayInputStream when you have an array of bytes, and you want to read from the array as if it were a file. If you just want to read arrays of bytes from the socket, do this:
InputStream stream = socket.getInputStream();
byte[] data = new byte[100];
int count = stream.read(data);
The variable count will contain the number of bytes actually read, and the data will of course be in the array data.
You can't get an instance of ByteArrayInputStream by reading directly from socket.
You require to read first and find byte content.
Then use it to create an instance of ByteArrayInputStream.
InputStream inputStream = socket.getInputStream();
// read from the stream
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] content = new byte[ 2048 ];
int bytesRead = -1;
while( ( bytesRead = inputStream.read( content ) ) != -1 ) {
baos.write( content, 0, bytesRead );
} // while
Now, as you have baos in hand, I don't think you still need a bais instance.
But, to make it complete,
you can generate byte array input stream as below
ByteArrayInputStream bais = new ByteArrayInputStream( baos.toByteArray() );

Socket: premature end of JPEG file

I'm trying to send an image file from a server to a client via a socket. The socket was previously used to send some strings from the server to the client (with buffered input/output streams).
The trouble is the image file can't be received properly, with "Premature end of JPEG file" error.
The server first sends the file size to the client, the client then creates a byte[] of that size, and starts to receive the file.
Here are the codes:
Server:
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//Send file size
dos.writeInt((int) file.length());
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(file));
byte[] fileBytes = new byte[bis.available()];
bis.read(fileBytes);
bis.close();
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
bos.write(fileBytes);
bos.flush();
Client:
DataInputStream dis = new DataInputStream(socket.getInputStream());
//Receive file size
int size = dis.readInt();
BufferedInputStream bis = new BufferedInputStream(socket.getInputStream());
byte[] fileBytes = new byte[size];
bis.read(fileBytes, 0, fileBytes.length);
More interestingly, if I let server sleep for about 2 seconds between sending the file size and writing the byte[], then the image is received properly. I wonder if there's some kind of race condition between the server and the client
The error is most likely here:
byte[] fileBytes = new byte[bis.available()];
The method available does not return the size of the file. It might return only the size of the input buffer, which is smaller than the size of the file. See the API documentation of the method in BufferedInputStream.
Also, read in the line below is not guaranteed to read the whole file in one go. It returns the number of bytes that were actually read, which can be less than what you asked for. And in the client code, you are using read in the same way, without actually checking if it read all the data.
Please check commons-io with FileUtils and IOUtils. This should make work a lot easier.
http://commons.apache.org/io/
The correct way to copy a stream in Java is as follows:
int count;
byte[] buffer = new byte[8192]; // more if you like, but over a network it won't make much difference
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Your code fails to logically match this at several points.
Also available() is not a valid way to determine either a file size or the size of an incoming network transmission - see the Javadoc. It has few if any correct uses and these aren't two of them.

Categories