Send a string between sockets in between bytes - java

I have 2 sockets connecting and sending a file. I want at some point send a signal to the second socket. I thought of sending a string "start" and when the receiver socket gets it, I execute something. Below is the code for receiver and sender. What am I doing wrong? The receiver never gets the "start" and I am sure its being sent. Thanks
Sender Side:
byte[] buff = new byte[1024 * 50];
while (isRunning && (readBytes = data.read(buff, 0, buff.length)) != -1) {
client.getOutputStream().write(buff, 0, readBytes);
if(sendStart){
client.getOutputStream().("start".getBytes("UTF-8"), 0, "start".getBytes("UTF-8").length);
sendStart = false;
}
}
Receiver Side:
DataInputStream in = null;
try {
in = new DataInputStream(socket.getInputStream());
} catch (IOException e) {
}
byte buffer[] = new byte[1024 * 50];
while ((len = in.read(buffer)) != -1) {
String received = new String(buffer, "UTF-8");
if(received!=null && received.equals("start")){
Log.d(TAG,"received start");
//do something
}
receivedFile.write(buffer, 0, len);
}

I think the error might be in here:
client.getOutputStream().("start".getBytes("UTF-8"), 0, "start".getBytes("UTF-8").length);
if you look, the write() method isn't anywhere on this line.
also, I wanted to ask, is there a particular reason you're handling the string serialization yourself? you could use something like PrintWriter and Scanner for strings, or you could use ObjectOutputStream and ObjectInputStream for any kind of object.

Related

How to transfer a file using sockets from an android java application to a C# windows application?

I built an application in java on android that sends the bytes of a .jpg file through a socket and an Asynchronous Server Socket in C# on windows that receives the bytes and writes them into a .jpg a file. The received file can't be open.
In the java application, which is the client, I used the folowing asynctask class executed on the onCreate:
class asyncTask extends AsyncTask<Void,Void,Void>{
#Override
protected Void doInBackground(Void... voids) {
try {
final File myFile = new File("//sdcard/DCIM/Camera/img1.jpg");
byte[] bytes = new byte[(int) myFile.length()];
BufferedInputStream buf = new BufferedInputStream(new FileInputStream(myFile));
buf.read(bytes, 0, bytes.length);
s = new Socket(ip,3333);
OutputStream OS = s.getOutputStream();
OS.write(bytes, 0, bytes.length);
OS.flush();
s.close();
} catch (IOException e) {
Log.d("Error",e.toString());
e.printStackTrace();
}
return null;
}
}
And in the C# application I received the data and saved it to a file in the following async callback method that is called when data is received:
public static void ReadCallback(IAsyncResult ar)
{
Socket clientSocket = (Socket)ar.AsyncState;
int buffLength = clientSocket.EndReceive(ar);
Array.Resize(ref buffer, buffLength);
totaLength += buffLength;
buffer.CopyTo(allData, totaLength - 1);
if (buffLength == 0)
{
Array.Resize(ref allData, totaLength);
File.WriteAllBytes("C: /Users/fxavi/Desktop/img.jpg", allData);
Console.WriteLine(totaLength);
}
else
clientSocket.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(ReadCallback), clientSocket);
}
buf.read(bytes, 0, bytes.length);
That will mostly not read the requested amount of bytes.length bytes.
Change that first to
int nread = buf.read(bytes, 0, bytes.length);
And compare nread to bytes.length and discover that they are not equal.
Further it is a bad idea to load a file completely in memory. Imagine you want to send a GB file.
Better make a loop where you read a chunck from the input stream and then write that chunck to the output stream.
I feel really stupid after finding the solution for this problem. Which is that totaLength += buffLength; should be executed before buffer.CopyTo(allData, totaLength); so that the buffer is copied to the right index.

Socket intermittently reads only 1448/2896 bytes

I am using Commons-IO to read and write from Socket. Things all works till payload size is either 1448/2896 max.
Below is the code snippet. Really unsure how to handle it.
Checked system buffer size too
$ cat /proc/sys/net/ipv4/tcp_wmem
4096 16384 4194304
public static void usingCommonsIO(){
Socket socket = null;
try {
socket = new Socket(serverIP, 55000);
IOUtils.write(request.getBytes(), socket.getOutputStream());
System.out.println("Message Sent....");
StringBuilder response = new StringBuilder();
String resp =IOUtils.toString(socket.getInputStream(), "UTF-8");
System.out.println(resp);
} catch (IOException e) {
e.printStackTrace();
}
}
Alternatively tried using DataInputStream but no luck. Code snipped is below.
public static void usingDataIOStream(String requestStr){
Socket socket = null;
try {
socket = new Socket("192.168.1.6", 55000);
System.out.println("Request Length -:" + request.length());
DataOutputStream out = new DataOutputStream(socket.getOutputStream());
out.write(requestStr.getBytes("UTF-8"), 0, requestStr.length());
out.flush();
System.out.println("Message Sent....");
DataInputStream din = new DataInputStream(socket.getInputStream());
byte[] response = new byte[16*1024];
int responseLength = din.read(response);
System.out.println("Response -:" + new java.lang.String(response, 0, responseLength));
} catch (IOException e) {
e.printStackTrace();
}
}
Confusing part is that the same code works with only 1448 bytes sometimes and max of 2896 bytes sometimes. There are no specific patterns.
Update 1
To simulate it, tried writing Server socket on my own and code is as below. Strange thing noticed with this is, on first request payload of size 6500 was read and received properly. Connection Reset from second request onwards. Am I missing something here?
public static void usingBAOS() throws IOException {
server = new ServerSocket(port);
Socket socket = null;
DataInputStream din = null;
DataOutputStream dos = null;
while (true) {
System.out.println("Waiting for Client...");
try {
// Accepting Client's connection
socket = server.accept();
System.out.println("Connnected to client " + socket.getInetAddress());
din = new DataInputStream(socket.getInputStream());
// Read request payload from Socket
String requestString = readRequest(din);
System.out.println("Request Read.....");
System.out.println("Writing Response.....");
// Writing response to socket
dos = writeResponse(socket, requestString);
} catch (IOException e) {
e.printStackTrace();
}finally {
//close resources
din.close();
System.out.println("InputStream is closed......");
dos.close();
System.out.println("OutputStream is closed......");
socket.close();
System.out.println("Socket is closed......");
}
}
}
private static DataOutputStream writeResponse(Socket socket, String requestString) throws IOException {
String responseString = "Hi Client" + requestString;
DataOutputStream dos = new DataOutputStream(socket.getOutputStream());
//write object to Socket
dos.write(responseString.getBytes(),0, responseString.getBytes().length);
dos.flush();
return dos;
}
private static String readRequest(DataInputStream din) throws IOException {
byte[] response = new byte[16*1024];
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int n = 0;
boolean read = true;
while(read){
n = din.read(response);
baos.write(response, 0, n);
if(baos.toString().length() == n){
read = false;
}
}
baos.flush();
String requestString = baos.toString();
return requestString;
}
Although this question is old at the time of writing this answer I'm putting this here for others in case it solves their problem. I encountered the same issue when using buffered data input and output streams on Android 8.0 devices where I had naively assumed that doing this:
int len = 2304;
byte[] data = new byte[len];
inputStream.read(data, 0, len);
would read all the data I sent down the socket. But as suggested by #Kayaman in the comments, this does not guarantee that len bytes of data are actually read from the buffer even if there are bytes available. In fact, this is in the documentation:
public final int read(byte[] b, int off, int len) throws IOException
Reads up to len bytes of data from the contained input stream into an array of bytes. An attempt is made to read as many as len bytes, but a smaller number may be read, possibly zero. The number of bytes actually read is returned as an integer.
In fact, if it doesn't read all the data, the only way to tell is to capture the returned value. My solution was then to monitor the amount of bytes actually read from the stream and just call read() in a loop as:
int i = 0;
len = 2304;
byte[] data = new byte[len];
while (i < len)
{
i += socket.inputStream.read(data, i, len - i);
}
Hope this helps someone.

Java file not working when sent over a network

So I was implementing client and socket for java. I wanted to send huge files on tcp through sockets and I was able to send files too but the only problem was the files on the other end were either not complete or not working. I have checked the bits are being transfered then what is the error.
Client side:
Socket sock = new Socket("127.0.0.1", 1056);
byte[] mybytearray = new byte[1024];
InputStream is = sock.getInputStream();
FileOutputStream fos = new FileOutputStream("abc.mp3");
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
int len = 0;
while((len = is.read(mybytearray)) != -1)
{
bos.write(mybytearray, 0, len);
System.out.println("sending");
}
bos.close();
sock.close();
Server side:
ServerSocket ss = new ServerSocket(1056);
while (true) {
Socket s = ss.accept();
PrintStream out = new PrintStream(s.getOutputStream());
BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
String info = null;
String request = null;
System.out.println("sending");
String filename = "abc.mp3";
File fi = new File(filename);
InputStream fs = new FileInputStream(fi);
int n = fs.available();
byte buf[] = new byte[1024];
out.println("Content_Length:" + n);
out.println("");
while ((n = fs.read(buf)) >= 0) {
out.write(buf, 0, n);
System.out.println("sending");
}
out.close();
s.close();
in.close();
}
When you are connected via TCP you create a network stream which you can read and write in, similar to all other streams you worked with. Writing a large amount of data to the stream is not a good idea, so I suggest you break the selected file into smaller packets in which each packet length is 1024 bytes (1KB) and then send all the packets to the server. The SendTCP function is as follows:(I have used Windows Forms to make things more obvious)
public void SendTCP(string M, string IPA, Int32 PortN)
{
byte[] SendingBuffer = null
TcpClient client = null;
lblStatus.Text = "";
NetworkStream netstream = null;
try
{
client = new TcpClient(IPA, PortN);
lblStatus.Text = "Connected to the Server...\n";
netstream = client.GetStream();
FileStream Fs = new FileStream(M, FileMode.Open, FileAccess.Read);
int NoOfPackets = Convert.ToInt32
(Math.Ceiling(Convert.ToDouble(Fs.Length) / Convert.ToDouble(BufferSize)));
progressBar1.Maximum = NoOfPackets;
int TotalLength = (int)Fs.Length, CurrentPacketLength, counter = 0;
for (int i = 0; i < NoOfPackets; i++)
{
if (TotalLength > BufferSize)
{
CurrentPacketLength = BufferSize;
TotalLength = TotalLength - CurrentPacketLength;
}
else
CurrentPacketLength = TotalLength;
SendingBuffer = new byte[CurrentPacketLength];
Fs.Read(SendingBuffer, 0, CurrentPacketLength);
netstream.Write(SendingBuffer, 0, (int)SendingBuffer.Length);
if (progressBar1.Value >= progressBar1.Maximum)
progressBar1.Value = progressBar1.Minimum;
progressBar1.PerformStep();
}
lblStatus.Text=lblStatus.Text+"Sent "+Fs.Length.ToString()+"
bytes to the server";
Fs.Close();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
finally
{
netstream.Close();
client.Close();
}
}
As you can see, a TCP client and a network stream are being constructed and a network connection is initiated. After opening the selected file according to the buffer size which is 1024 bytes, the number of packets that are going to be sent is calculated. There are two other variables CurrentPacketLength and TotalLength. If the total length of the selected file is more than the buffer size the CurrentPacketLength is set to the buffer size, otherwise why send some empty bytes, so CurrentPacketLength is set to the total length of the file. After that, I subtract the current from the total length, so actually we can say total length is showing the total amount of data that has not been sent yet. The rest is pretty much straight forward, reading the data from the file stream and writing it to the SendingBuffer according to the CurrentPacketLength and writing the buffer to the network stream.
At the server side, the application is listening for an incoming connection:
public void ReceiveTCP(int portN)
{
TcpListener Listener = null;
try
{
Listener = new TcpListener(IPAddress.Any, portN);
Listener.Start();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
byte[] RecData = new byte[BufferSize];
int RecBytes;
for (; ; )
{
TcpClient client = null;
NetworkStream netstream = null;
Status = string.Empty;
try
{
string message = "Accept the Incoming File ";
string caption = "Incoming Connection";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
DialogResult result;
if (Listener.Pending())
{
client = Listener.AcceptTcpClient();
netstream = client.GetStream();
Status = "Connected to a client\n";
result = MessageBox.Show(message, caption, buttons);
if (result == System.Windows.Forms.DialogResult.Yes)
{
string SaveFileName=string.Empty;
SaveFileDialog DialogSave = new SaveFileDialog();
DialogSave.Filter = "All files (*.*)|*.*";
DialogSave.RestoreDirectory = true;
DialogSave.Title = "Where do you want to save the file?";
DialogSave.InitialDirectory = #"C:/";
if (DialogSave.ShowDialog() == DialogResult.OK)
SaveFileName = DialogSave.FileName;
if (SaveFileName != string.Empty)
{
int totalrecbytes = 0;
FileStream Fs = new FileStream
(SaveFileName, FileMode.OpenOrCreate, FileAccess.Write);
while ((RecBytes = netstream.Read
(RecData, 0, RecData.Length)) > 0)
{
Fs.Write(RecData, 0, RecBytes);
totalrecbytes += RecBytes;
}
Fs.Close();
}
netstream.Close();
client.Close();
}
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
//netstream.Close();
}
}
}
A TCP listener is created and starts listening to the specified port. Again the buffer size is set to 1024 bytes. A TCP listener can pre check to see if there are any connections pending before calling the AcceptTcpClient method. It returns true if there are any pending connections. This method is a good way of avoiding the socket being blocked. Before reading anything from the network stream, a message box asks you if you want to accept the incoming connection, then a SaveFileDialog will be opened, and when you enter the file name plus extension, a file stream will be constructed and you start reading from the network stream and writing to the file stream. Create a thread in your code and run the receiving method in the created thread. I have sent more than 100 MB files in a LAN with the application.
For more details, check this article.
So, first you do this
int bytesRead = is.read(mybytearray, 0, mybytearray.length);
That reads up to 1024 bytes into mybytearray.
You don't do anything with that and I don't understand why you are doing it. You never write those bytes so they get overwritten if the while loop reads anything.
Just delete that. The while loop should cover all of this.

Sending file from one client to another client using socket in java

Hello everyone ,
I am trying to develop the application for transfering/sending the file like SKYPE works.So I am using socket for transfering file from one computer(client) to another computer(client) .I am able to transfer file from one client to server using this. code.But when I try to send the same file from server to second client.It is transfering with 0 byte also give socket close exception so I try to create new socket object at client side.So Now the Exception not coming but file not transfering to client.After debugging I found that the file is successfully sent to client by server but at client side socket is not able to read the data and waiting for data.I can’t find any better solution.If anyone knows anything about this Please tell me.If you have any other solution for file transfer than also tell me.Thanks in advance
Below is my code
Server code:
public class ChatServer
{
serversocket = new ServerSocket(1436);
thread = new Thread(this);
thread.start();
/*************Thread Implementation***************/
public void run()
{
/*********Accepting all the client connections and create a seperate thread******/
while(thread != null)
{
try
{
/********Accepting the Server Connections***********/
socket = serversocket.accept();
/******* Create a Seperate Thread for that each client**************/
chatcommunication = new ChatCommunication(this,socket);
thread.sleep(THREAD_SLEEP_TIME);
}
catch(InterruptedException _INExc) { ExitServer(); }
catch(IOException _IOExc) { ExitServer(); }
}
}
protected void SendGroupFile(Socket ClientSocket, String FileName,String GroupName,String UserName) throws IOException
{
try
{
// receive file from Client
byte [] mybytearray = new byte [filesize];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(Filepath);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead;
do {
bytesRead =is.read(mybytearray, current, (mybytearray.length-current));
System.out.println("Reading Bytes server"+bytesRead);
if(bytesRead >= 0)
current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray,0,current);
bos.flush();
bos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
/***** Function To Send a File to Client **********/
protected void SendGroupFileClient(Socket ClientSocket, String FileName,String GroupName,String UserName)
{
try {
int m_userListSize = userarraylist.size();
clientobject = GetClientObject(GroupName);
if(clientobject != null)
for(G_ILoop = 0; G_ILoop < m_userListSize; G_ILoop++)
{
clientobject = (ClientObject) userarraylist.get(G_ILoop);
if((clientobject.getGroupName().equals(GroupName)) && (!(clientobject.getUserName().equals(UserName))))
{
{
File myFile = new File (Filepath);
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
os = socket.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
}
}catch(IOException _IOExc)
{
_IOExc.printStackTrace();
}
}
}
ChatCommunication .java
public class ChatCommunication implements Runnable,CommonSettings
{
Thread thread;
Socket socket;
DataInputStream inputstream;
String RFC;
ChatServer Parent;
/********Initialize the Socket to the Client***********/
ChatCommunication(ChatServer chatserver,Socket clientsocket)
{
Parent = chatserver;
socket = clientsocket;
try
{
inputstream = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
}catch(IOException _IOExc) { }
thread = new Thread(this);
thread.start();
}
public void run()
{
while(thread != null)
{
try {
RFC = inputstream.readLine();
if(RFC.startsWith("FILEGRUP"))
{
Parent.SendGroupFile(socket,RFC.substring(9,RFC.indexOf("!")),RFC.substring(RFC.indexOf("!")+1,RFC.indexOf("*")),RFC.substring(RFC.indexOf("*")+1));
}
if(RFC.startsWith("FILEGET"))
{
Parent.SendGroupFileClient(socket,RFC.substring(8,RFC.indexOf("!")),RFC.substring(RFC.indexOf("!")+1,RFC.indexOf("*")),RFC.substring(RFC.indexOf("*")+1));
}
}catch(Exception _Exc)
{
Parent.RemoveUserWhenException(socket);QuitConnection();
}
}
}
Client code
class Client extends JFrame
{
ServerName="192.168.1.103";
ServerPort=1436;
Client()
{
socket = new Socket(ServerName,ServerPort);
SendGroupFileToServer(Filepath,SelectedGroup);
}
/*******Function To Send File To Server and receiving the file ***********/
protected void SendGroupFileToServer(String FileName, String ToGroup)
{
try {
dataoutputstream.writeBytes(FileName.concat("!").concat(ToUser)+"\r\n");
//send file to sever
File myFile = new File (FileName.substring(9));
byte [] mybytearray = new byte [(int)myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
bis.read(mybytearray,0,mybytearray.length);
OutputStream os = socket.getOutputStream();
System.out.println("Sending...");
os.write(mybytearray,0,mybytearray.length);
os.flush();
os.close();
System.out.println("File successfully Sended to server");
}catch(IOException _IoExc) { QuitConnection(QUIT_TYPE_DEFAULT);}
try {
socket1 = new Socket(ServerName,ServerPort); //Creating new Socket
dataoutputstream = new DataOutputStream(socket1.getOutputStream());
dataoutputstream.writeBytes("FILEGET"+FileName.concat("!").concat(ToGroup+"*"+UserName)+"\r\n"); //sending string to server
} catch (IOException e1) {
e1.printStackTrace();
}
// receive file sended by server
byte [] mybytearray = new byte [filesize];
InputStream is;
try {
is = socket1.getInputStream();
FileOutputStream fos = new FileOutputStream(Filepath);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(mybytearray,0,mybytearray.length);
current = bytesRead; //up to this working fine
do {
bytesRead =is.read(mybytearray, current, (mybytearray.length-current)); //not reading the file data sent by server just waiting and not go ahead
if(bytesRead >= 0)
current += bytesRead;
} while(bytesRead > -1);
bos.write(mybytearray,0,current);
bos.flush();
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
There are so many problems here that it is difficult to know where to start.
The thread.sleep() in the accept() loop is literally a waste of time. It serves no useful purpose except possibly to throttle the rate at which clients are accepted. If that wasn't your intention, don't do it.
All you are doing when you catch an exception is exiting the server without even printing the exception message. So when something goes wrong, as it is here, you can't possibly know what it was. Don't do that.
readLine() returns null at EOS, on which you must close the socket, stop reading, and exit the thread. You aren't testing that, and you are therefore omitting all three of those required steps. Don't do that.
You are constructing a DataInputStream around a BufferedInputStream for use when reading commands, but you aren't passing it to the methods that process those commands. You are just passing the socket. You are therefore losing data. Don't do that. Every part of the program must use the same input stream or reader for the socket.
You are reading the entire file into memory. This (a) assumes the file size fits into an int; (b) does not scale to large files; (c) wastes space, and (d) adds latency. Don't do that.
You are ignoring the result of the read() into that buffer and assuming it was filled. You can't do that. The correct way to copy streams in Java is shown below. This works with a buffer of any size, e.g. 8192, for an input of any length, and doesn't require you to buffer the entire input into memory. You can use this loop at both the client when sending the file and at the server when receiving it.
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
Similarly to (4) above, you are using a DataOutputStream around a BufferedOutputStream for some things and the socket output stream directly for others. Don't do that. All parts of the program must the same output stream or writer for the socket.
You don't need to flush() before close(); it happens automatically.
For some reason after sending the file you are creating a new connection and sending another command. You aren't even closing the connection afterwards. The server will have no easy way of knowing that this connection and this command referred to the file just sent in the code above. It is also redundant, as the receipt of the final EOS tells the server that the file has been sent successfully. Don't do this. If you need to send more information with the file, send it first, before the file, on the same connection.
The reference you cite exhibits many of the above issues. Make an effort to find a reputable starting point.
This is the solution. Please Apply this logic to your code.
I am able to send a file from server to client and client to server.
Check the following code to send the file from Client to Server. It is working great.
If you have any issues let me know.
Server Side Code:
public class ServerRecieveFile {
public static void main(String[] args) throws IOException {// TODO Auto-enerated method stub int filesize=1022386;
int bytesRead; int currentTot= ;
ServerSocket serverSocket=new ServerSocket(15123);
Socket socket=rverSocket.accept();
byte [] bytearray = new byte [filesize];
InputStream is=socket.getInputStream();
File copyFileName=new File("c:/Files Sockets/2.txt");
FileOutputStream fos = new FileOutputStream(copyFileName);
BufferedOutputStream bos = new BufferedOutputStream(fos);
bytesRead = is.read(bytearray,0,bytearray.length);
currentTot = bytesRead;
do {
bytesRead =is.read(bytearray, currentTot, (bytearray.length-currentTot)); if(bytesRead >= 0)
currentTot += bytesRead;
} while(bytesRead > -1);
bos.write(bytearray, 0 , currentTot);
bos.flush();
bos.close();
socket.close();
}
}
Client Side code:
public class ClientSendFile {
public static void main(String[] args) throws UnknownHostException, IOException {// TODO Auto-generated method stub
Client client=new Client();
Socket socket = new Socket(InetAddress.getLocalHost(),15123);
System.out.println("Accepted connection : " + socket);
File transferFile = new File ("c:/Files Sockets/1.txt");
byte [] bytearray = new byte (int)transferFile.length()];
FileInputStream fin = new FileInputStream(transferFile);
BufferedInputStream bin = new BufferedInputStream(fin);
bin.read(bytearray,0,bytearray.length);
OutputStream os = socket.getOutputStream();
System.out.println("Sending Files...");
os.write(bytearray,0,bytearray.length);
os.flush();
socket.close();
System.out.println("File transfer complete");
}
}

How to write RAW data to a file using Java? e.g same as: nc -l 8000 > capture.raw

In TCP i am receiving media stream from an IP camera as RAW. According to there advise, i need to write that as file. And then i can play it with media player such as VLC.
But when i write this to a file, and play with media players it never play corrupted.
After comparing the original file i see my Java writing it in wrong characters. And there sample file shows different. What or how do i fix such file writing issue, here is how i am writing it:
byte[] buf=new byte[1024];
int bytes_read = 0;
try {
bytes_read = sock.getInputStream().read(buf, 0, buf.length);
String data = new String(buf, 0, bytes_read);
System.err.println("DATA: " + bytes_read + " bytes, data=" +data);
BufferedWriter out = new BufferedWriter(
new FileWriter("capture.ogg", true));
out.write(data);
out.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}
You shouldn't use Readers, Writers and Strings for binary data. Stick with InputStreams and OutputStreams.
I.e., change
BufferedWriter -> BufferedOutputStream,
FileWriter -> FileOutputStream
and instead of String, just use a byte[].
If you're dealing with sockets, I must advice you to look into the NIO package though.
You're doing it right... at least until the part where you turn your byte[] into a String:
That step only really makes sense if your byte[] represents textual data in the first place! Which it doesn't!
Whenever you handle binary data or don't actually care what the data represents you must avoid using String/Reader/Writer to handle that data. Instead do use byte[]/InputStream/OutputStream.
Also, you must read from the socket in a loop, because nothing guarantees that you've read everything:
byte[] buf=new byte[1024];
int bytes_read;
OutputStream out = new FileOutputStream("capture.ogg", true);
InputStream in = sock.getInputStream();
while ((bytes_read = in.read(buf)) != -1) {
out.write(buf, 0, bytes_read);
}
out.close();
The way you have it written limits the output file to a maximum size of 1024 bytes. Try a loop:
try {
byte[] buf = new byte[1024];
int bytes_read = 0;
InputStream in = sock.getInputStream();
FileOutputStream out = new FileOutputStream(new File("capture.ogg"));
do {
bytes_read = in.read(buf, 0, buf.length);
System.out.println("Just Read: " + bytes_read + " bytes");
if (bytes_read < 0) {
/* Handle EOF however you want */
}
if (bytes_read > 0)
out.write(buf, 0, bytes_read);
} while (bytes_read >= 0);
out.close();
} catch (IOException e) {
e.printStackTrace(System.err);
}

Categories

Resources