I am developing application which will send some files from one android device to an other device. One device will create a hot spot and will use the web browser to receive some files from the other device which will connect to the hot spot using WiFi. I do not known to much about HTTP. I have created simple sever in the sending device. The receiving device will connect to the server with its web browser. When i write the (IP:port number ) in the browser, it say "starting download" but the download does not finished. in the sending device i get IOException: sendto failed EPIPE (Broken pipe) .
my code is
boolean sending_done = false;
while (! sending_done)
{
Socket socket = null;
try
{
socket = serverSocket.accept();
OutputStream outputStream = socket.getOutputStream();
outputStream.write("HTTP/1.1 200 OK\r\n".getBytes());
outputStream.write("Content-Type: application/zip\r\n".getBytes());
outputStream.write("Content-Disposition: attachment; filename=files.zip\r\n".getBytes());
outputStream.write("Content-Encoding: gzip\r\n".getBytes());
outputStream.write("Transfer-Encoding: chunked\r\n".getBytes());
outputStream.write("\r\n".getBytes());
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(outputStream);
ZipOutputStream zipOutputStream = new ZipOutputStream(bufferedOutputStream);
zipOutputStream.setLevel(ZipOutputStream.STORED);
sendFiles(zipOutputStream, to_send_files_array_list);
byte[] CRLF ="\r\n".getBytes();
writ_header(0, zipOutputStream, CRLF);
zipOutputStream.write(CRLF, 0, CRLF.length);
zipOutputStream.finish();
zipOutputStream.flush();
zipOutputStream.close();
sending_done = true;
}
catch (IOException e)
{
e.printStackTrace();
display_toast(e.toString());
}
finally
{
try
{
if (socket != null)
{
socket.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
private void sendFiles(ZipOutputStream zipOutputStream, ArrayList<File> filesToSend)
{
byte[] CRLF ="\r\n".getBytes();
for(File file: filesToSend)
{
BufferedInputStream bufferedInputStream = null;
ZipEntry zipEntry = null;
try
{
FileInputStream fileInputStream = new FileInputStream(file);
bufferedInputStream = new BufferedInputStream(fileInputStream);
zipEntry = new ZipEntry(file.getName());
zipOutputStream.putNextEntry(zipEntry);
int x;
byte[] buffer = new byte[buffer_size];
while ((x= bufferedInputStream.read(buffer))!= -1)
{
if (x>0)
{
writ_header(x, zipOutputStream, CRLF);
zipOutputStream.write(buffer,0,x);
zipOutputStream.write(CRLF, 0, CRLF.length);
}
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
if (zipEntry != null)
{
zipOutputStream.closeEntry();
}
if (bufferedInputStream != null)
{
bufferedInputStream.close();
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
private void writ_header(int length, OutputStream outputStream, byte[] CRLF) throws IOException
{
byte[] header = Integer.toHexString(length).getBytes();
outputStream.write(header, 0, header.length);
outputStream.write(CRLF, 0, CRLF.length);
}
Related
So I have this thing that I'm making and the problem is that I think that some bytes are lost while the file is compressed and send to server as well as saved locally. I was able to send data while not using ByteArrayOutputStream but I have to use it and can't just use socket's OutputStream directly as I need each sent file to have somwhat unique ID. Also sizes of out.zip and out2.zip are different by around 10kB (out2.zip is smaller)
here is Log dump: https://pastebin.com/UyTqnRYc
Function that sends data in chunks
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipParameters zipParameters = buildZipParameters(compressionMethod);
ObjectOutputStream objOS = new ObjectOutputStream(outputStream);
File f = new File("out2.zip");
FileOutputStream fos = new FileOutputStream(f);
for (File directory:pathsToDirectories) {
String relativeRootDirectory = directory.getName();
List<File> filesAndDirectories = Arrays.stream(Objects.requireNonNull(directory.listFiles())).toList();
for (File somefile:filesAndDirectories) {
if(somefile.isDirectory()){
addDirectoryToZip(zos,somefile,zipParameters,relativeRootDirectory,rootDirectoryName);
}
else
{
if (zipParameters.getCompressionMethod() == CompressionMethod.STORE) {
zipParameters.setEntrySize(somefile.length());
}
byte[] buff = new byte[4096];
zipParameters.setFileNameInZip(rootDirectoryName+ "/"+somefile.getName()); //YIKES
zos.putNextEntry(zipParameters);
try(InputStream inputStream = new FileInputStream(somefile)) {
int readLen;
while (((readLen = inputStream.read(buff)) != -1)) {
zos.write(buff);
byte[] b = baos.toByteArray();
System.out.println("written :"+baos.toByteArray().length);
objOS.writeObject(new TransportDataModel((byte) 1,baos.toByteArray()));
fos.write(baos.toByteArray());
baos.reset();
baos.flush();
}
}
zos.closeEntry();
}
}
}
objOS.writeObject(new TransportDataModel((byte) 1,baos.toByteArray()));
zos.flush();
System.out.println("REST OF IT :"+ Arrays.toString(baos.toByteArray()));
System.out.println(baos.toByteArray().length);
objOS.writeObject(new TransportDataModel((byte) 1,baos.toByteArray()));
fos.write(baos.toByteArray());
baos.reset();
System.out.println("REST OF IT :"+ Arrays.toString(baos.toByteArray()));
fos.flush();
fos.close();
objOS.writeObject(new TransportDataModel((byte) -1,new byte[0]));
zos.close();
}
Record used as a packet
import java.io.Serializable;
public record TransportDataModel(byte id, byte[] data) implements Serializable {
}
Server code:
public Server(int port)
{
// starts server and waits for a connection
try
{
server = new ServerSocket(port);
System.out.println("Server started");
System.out.println("Waiting for a client ...");
socket = server.accept();
System.out.println("Client accepted");
in = new ObjectInputStream(socket.getInputStream());
File f = new File("out.zip");
FileOutputStream outputStream = new FileOutputStream(f);
TransportDataModel transportDataModel;
while (true) {
transportDataModel= (TransportDataModel) in.readObject();
if (transportDataModel.id() == -1) {
break;
}
if(transportDataModel.data().length != 0)
{
//System.out.println(transportDataModel.id());
outputStream.write(transportDataModel.data());
}
}
outputStream.flush();
outputStream.close();
System.out.println("Closing connection");
// close connection
socket.close();
in.close();
ZipFile zipFile = new ZipFile("out.zip");
zipFile.extractAll("/home/xenu/IdeaProjects/BBT-BasicBackupTool");
}
catch(IOException i)
{
i.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
I am downloading a zip file from dropbox. When it keeps downloading I measure the file size and get it is increasing its size with the Below code. It downloads whole 84M and after finishing download it turns into 0 bytes. What wrong am I actually doing?
public static void downloadDropBox(File file) {
String url = "https://www.dropbox.com/sh/jx4b2wvqg8d4ze1/AAA0J3LztkRc6FJ5tKy4dUKha?dl=1";
int bytesRead;
byte[] bytesArray = new byte[1024];
InputStream is = null;
FileOutputStream outputStream = null;
long progres = 0;
try {
URL fileUrl = new URL(url);
HttpURLConnection connection = (HttpURLConnection)fileUrl.openConnection();
connection.connect();
is = connection.getInputStream();
outputStream = new FileOutputStream(file);
while ((bytesRead = is.read(bytesArray, 0, 1024)) != -1) {
outputStream.write(bytesArray, 0, bytesRead);
}
}
} catch (Exception e) {
e.printStackTrace();
}
finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (outputStream != null) {
try {
outputStream.flush();
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
During download file:
After Finishing download file:
I want sends and receive an object and file the order is
client -> server by ObjectOut(In)putStream
client -> server String(file name) by DataIn(Out)putStrean writeUTF
client -> server by BufferedIn(Out)putStream
server -> client by ObjectOut(In)putStream
but when the code reaches on 3 writing file takes forever (I think...it is waiting) the critical code is
byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
bos.write(data, 0, length);
System.out.println(length);
}
bis(BufferedInputStream).read() do not proceed when I print the length the output is
4096
4096
879
then just wait...
is there anyone who knows what is the problem or solution?
Server thread
public void run() {
System.out.println("\n New FileUploadServer thread started");
msg = (Message) objComm.recvObject(clientSocket);
System.out.println("server get message");
if (checkState(msg.getState()))
System.out.println(clientAddr + " session over");
System.out.println("");
}
private boolean checkState(int _state) {
switch (_state) {
case ST_EXCEL_FILE:
return receiveExcel();
default:
return false;
}
}
private boolean receiveExcel() {
Message sendMsg = receiveStr();
System.out.println("receiveStr() success");
BufferedInputStream bis;
DataOutputStream dos;
DataInputStream dis;
FileOutputStream fos;
BufferedOutputStream bos;
VoteInfo sendVoteInfo = (VoteInfo) msg.getObj();
try {
dis = new DataInputStream(clientSocket.getInputStream());
dos = new DataOutputStream(clientSocket.getOutputStream());
// check file name extension is "xls" or "xlsx"
String fName = dis.readUTF();
int idx = fName.lastIndexOf(".");
String extension = fName.substring(idx + 1, fName.length());
if (!excelFileCheck(extension))
return false;
dos.writeUTF("read_ok");
dos.flush();
System.out.println("File name: " + fName);
File f = new File(EXCEL_FILE_DIR + fName);
fos = new FileOutputStream(f);
bos = new BufferedOutputStream(fos);
bis = new BufferedInputStream(clientSocket.getInputStream());
int length;
byte[] data = new byte[BUFFER_SIZE];
while ((length = bis.read(data)) != -1) {
bos.write(data, 0, length);
System.out.println(length);
}
bos.flush();
// send success message to web server
System.out.println("kangji2");
objComm.sendObject(sendMsg, clientSocket);
System.out.println("File receive success!");
if (!dataToDB.excelToDB(EXCEL_FILE_DIR + fName, extension)) {
//delete all db related to this excel file here
return false;
} else {
}
bos.close();
fos.close();
dis.close();
clientSocket.close();
// send candidates information to DB server
return makeResult(sendVoteInfo);
} catch (IOException e) {
System.out.println("ReceiveExcel error");
e.printStackTrace();
}
return false;
}
public class ObjectComm {
private Message receiveMsg = null;
private ObjectOutputStream out = null;
private ObjectInputStream in = null;
public Message commObject(Message _sendMsg, Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return null;
}
try {
out = new ObjectOutputStream(_clntSocket.getOutputStream());
out.writeObject(_sendMsg);
out.flush();
System.out.println("kangji1");
in = new ObjectInputStream(_clntSocket.getInputStream());
receiveMsg = (Message) in.readObject();
System.out.println("kangji2");
return receiveMsg;
} catch (Exception e) {
System.out.println("commObject err");
e.printStackTrace();
return null;
}
}
public boolean sendObject(Message _msg, Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return false;
}
try {
out = new ObjectOutputStream(_clntSocket.getOutputStream());
out.writeObject(_msg);
out.flush();
return true;
} catch (IOException e) {
System.out.println("Object comm send err");
e.printStackTrace();
return false;
}
}
public Message recvObject(Socket _clntSocket) {
if (!_clntSocket.isConnected()) {
System.out.println("clnt Socket not connected");
return null;
}
try {
in = new ObjectInputStream(_clntSocket.getInputStream());
receiveMsg = (Message) in.readObject();
return receiveMsg;
} catch (Exception e) {
System.out.println("Object comm recvObject err");
e.printStackTrace();
return null;
}
}
}
Did you close the connection in client side (sender side, or wherever opposite of your input stream) ? read(byte[], int, int ) in BufferedInputStream will return when end of the stream has been reached.
http://docs.oracle.com/javase/7/docs/api/java/io/BufferedInputStream.html#read(byte[],%20int,%20int)
client -> server by ObjectOut(In)putStream
client -> server String(file name) by DataIn(Out)putStrean writeUTF
client -> server by BufferedIn(Out)putStream
server -> client by ObjectOut(In)putStream
Too much stuff here.
Playing with streams at different levels of your stream stack simply does not work.
If you want to send objects, use the ObjectInput/OutputStreams for everything. Construct them as follows:
new ObjectOutputStream(new BufferedOutputStream(...))
and
new ObjectInputStream(new BufferedInputStream(...))
Send the objects with writeObject(); send the strings with writeObject() or writeUTF(); send byte arrays via ObjectOutputStream.write(); and use the complementary methods of ObjectInputStream at the other end.
I am trying to record audio into a file in the server side which is an android device and send it to client, another android device when the record is done. It works fine for the first time, but when I record again, my second record is not received by the client. Here is my code
SERVER THREAD:
public class ServerThread implements Runnable {
public void run() {
try {
if (SERVERIP != null) {
serverSocket = new ServerSocket(SERVERPORT);
while (true) {
client = serverSocket.accept();
OutputStream out = client.getOutputStream();
while(true){
//record status is true
//when record is done
if(record_status){
try {
BufferedInputStream bis = new BufferedInputStream(new FileInputStream(new File(mFileName)));
BufferedOutputStream bout = new BufferedOutputStream(out);
copyFile(bis, bout);
bout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
record_status = false;
}
}
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
CLIENT THREAD:
public class ClientThread implements Runnable {
public void run() {
try {
InetAddress serverAddr = InetAddress.getByName(SERVERIP);
Socket socket = new Socket(serverAddr, SERVERPORT);
connected = true;
while (connected) {
try {
dis = socket.getInputStream();
while(true){
if(dis.available()>0){
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(new File(mFileName)));
copyFile(socket.getInputStream(), bos);
bos.flush();
//file has been received
//start playing the audio
startPlaying();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
socket.close();
} catch (Exception e) {
connected = false;
}
}
}
method copyFile:
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[4092];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
} catch (IOException e) {
return false;
}
return true;
}
This really should be a comment, however i don't have the rep yet. But it seems to me that on the server side you have record_status set to true on first iteration of while loop once that stream is sent to client then record_status is set false and never actually set to true again inside the while loop. As a result the code inside the if statement is never executed again. So where does record_status get set to true again? check the logcat on server side device to see if anything is actually put into bitstream for the second recording if not this is your problem
This is re-worded from a previous question (which was probably a bit unclear).
I want to download a text file via FTP from a remote server, read the contents of the text file into a string and then discard the file. I don't need to actually save the file.
I am using the Apache Commons library so I have:
import org.apache.commons.net.ftp.FTPClient;
Can anyone help please, without simply redirecting me to a page with lots of possible answers on?
Not going to do the work for you, but once you have your connection established, you can call retrieveFile and pass it an OutputStream. You can google around and find the rest...
FTPClient ftp = new FTPClient();
...
ByteArrayOutputStream myVar = new ByteArrayOutputStream();
ftp.retrieveFile("remoteFileName.txt", myVar);
ByteArrayOutputStream
retrieveFile
Normally I'd leave a comment asking 'What have you tried?'. But now I'm feeling more generous :-)
Here you go:
private void ftpDownload() {
FTPClient ftp = null;
try {
ftp = new FTPClient();
ftp.connect(mServer);
try {
int reply = ftp.getReplyCode();
if (!FTPReply.isPositiveCompletion(reply)) {
throw new Exception("Connect failed: " + ftp.getReplyString());
}
if (!ftp.login(mUser, mPassword)) {
throw new Exception("Login failed: " + ftp.getReplyString());
}
try {
ftp.enterLocalPassiveMode();
if (!ftp.setFileType(FTP.BINARY_FILE_TYPE)) {
Log.e(TAG, "Setting binary file type failed.");
}
transferFile(ftp);
} catch(Exception e) {
handleThrowable(e);
} finally {
if (!ftp.logout()) {
Log.e(TAG, "Logout failed.");
}
}
} catch(Exception e) {
handleThrowable(e);
} finally {
ftp.disconnect();
}
} catch(Exception e) {
handleThrowable(e);
}
}
private void transferFile(FTPClient ftp) throws Exception {
long fileSize = getFileSize(ftp, mFilePath);
InputStream is = retrieveFileStream(ftp, mFilePath);
downloadFile(is, buffer, fileSize);
is.close();
if (!ftp.completePendingCommand()) {
throw new Exception("Pending command failed: " + ftp.getReplyString());
}
}
private InputStream retrieveFileStream(FTPClient ftp, String filePath)
throws Exception {
InputStream is = ftp.retrieveFileStream(filePath);
int reply = ftp.getReplyCode();
if (is == null
|| (!FTPReply.isPositivePreliminary(reply)
&& !FTPReply.isPositiveCompletion(reply))) {
throw new Exception(ftp.getReplyString());
}
return is;
}
private byte[] downloadFile(InputStream is, long fileSize)
throws Exception {
byte[] buffer = new byte[fileSize];
if (is.read(buffer, 0, buffer.length)) == -1) {
return null;
}
return buffer; // <-- Here is your file's contents !!!
}
private long getFileSize(FTPClient ftp, String filePath) throws Exception {
long fileSize = 0;
FTPFile[] files = ftp.listFiles(filePath);
if (files.length == 1 && files[0].isFile()) {
fileSize = files[0].getSize();
}
Log.i(TAG, "File size = " + fileSize);
return fileSize;
}
You can just skip the download to local filesystem part and do:
FTPClient ftpClient = new FTPClient();
try {
ftpClient.connect(server, port);
ftpClient.login(user, pass);
ftpClient.enterLocalPassiveMode();
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
InputStream inputStream = ftpClient.retrieveFileStream("/folder/file.dat");
BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "Cp1252"));
while(reader.ready()) {
System.out.println(reader.readLine()); // Or whatever
}
inputStream.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
try {
if (ftpClient.isConnected()) {
ftpClient.logout();
ftpClient.disconnect();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}