I'm trying to build an Android app to perform upload speed tests using FTP, but with the following code, the upload speed doesn't go above 1 Mbps. While using an FTP client on the same device, I can get upload speeds of 15 Mbps. Can someone give me a help on this?
public class MultiUL extends Thread{
private String id="hhhhh0001";
private int bufferSize=32768;
public void run() {
FTPClient ftp = new FTPClient();
try {
ftp.connect(MPSharkVar.Server,21); // Using port no=21
ftp.login(MPSharkVar.FTPUser, MPSharkVar.FTPPwd);
ftp.setFileType(FTP.BINARY_FILE_TYPE);
ftp.enterLocalPassiveMode();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
uploadWork(ftp, id);
try {
ftp.disconnect();
}
catch (Exception ex)
{
}
}
private void uploadWork(FTPClient ftp, String id) {
byte[] buffer = new byte[bufferSize];
for (int i = 0; i < bufferSize; i++) {
buffer[i] = 'F';
}
OutputStream os = null;
BufferedOutputStream bos = null;
long start = System.currentTimeMillis();
long end = start;
try {
ftp.changeWorkingDirectory("/upload");
os = ftp.storeFileStream(id);
bos = new BufferedOutputStream(os);
start = System.currentTimeMillis();
end = start;
while (((end - start) <= MPSharkVar.TestDur)) {
bos.write(buffer, 0, buffer.length);
end = System.currentTimeMillis();
}
} catch (Exception ex) {
end = System.currentTimeMillis();
} finally {
try {
bos.flush();
bos.close();
os.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Related
I'm trying to exchange files between two devices using android wifi direct. Any of the device can send and receive files. After discovering and connecting the two devices,I can only successfully send and receive a file/files upon the first time calling send. I'm unable to send any file afterwards. In addition,transfer speed is very slow(it takes about three minutes to transfer a 10mb file)
void startServer(){
String intRoot = new FilesDisplayFragment().internalDirRoot;
ExecutorService serverExecutor = newSingleThreadExecutor();
serverExecutor.submit(new Runnable() {
#Override
public void run() {
ServerSocket serverSocket = null;
try {
serverSocket = new ServerSocket(8888);
} catch (IOException e) {
e.printStackTrace();
}
try {
socket = serverSocket.accept();
} catch (IOException e) {
e.printStackTrace();
}
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
DataInputStream dis = new DataInputStream(bis);
int filesCount = 0;
try {
filesCount = dis.readInt();
} catch (IOException e) {
e.printStackTrace();
}
File[] files = new File[filesCount];
for(int i = 0; i < filesCount; i++)
{
long fileLength = 0;
try {
fileLength = dis.readLong();
} catch (IOException e) {
e.printStackTrace();
}
String fileType = null;
try {
fileType = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
String fileName = null;
try {
fileName = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
if (fileType == "apk"){
File dirs = new File(intRoot + "RemoteView/" + "app");
if(!dirs.exists()) dirs.mkdirs();
files[i] = new File(dirs.toString() + "/" + fileName);
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(files[i]);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedOutputStream bos = new BufferedOutputStream(fos);
for(int j = 0; j < fileLength; j++) {
try {
bos.write(bis.read());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
void startClient(Intent intent){
socket = new Socket();
String intRoot = new FilesDisplayFragment().internalDirRoot;
Parcelable parcelable = intent.getParcelableExtra("hostAdd");
Parceler parceler = Parcels.unwrap(parcelable);
String hostAdd = parceler.getGroupOwnerAddress().getHostAddress();
ExecutorService clientExecutor = newSingleThreadExecutor();
clientExecutor.submit(new Runnable() {
#Override
public void run() {
try {
socket.connect(new InetSocketAddress(hostAdd, 8888), 5000);
} catch (IOException e) {
e.printStackTrace();
}
BufferedInputStream bis = null;
try {
bis = new BufferedInputStream(socket.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
DataInputStream dis = new DataInputStream(bis);
int filesCount = 0;
try {
filesCount = dis.readInt();
} catch (IOException e) {
e.printStackTrace();
}
File[] files = new File[filesCount];
for(int i = 0; i < filesCount; i++)
{
long fileLength = 0;
try {
fileLength = dis.readLong();
} catch (IOException e) {
e.printStackTrace();
}
String fileType = null;
try {
fileType = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
String fileName = null;
try {
fileName = dis.readUTF();
} catch (IOException e) {
e.printStackTrace();
}
if (fileType == "apk"){
File dirs = new File(intRoot + "RemoteView/" + "app");
if(!dirs.exists()) dirs.mkdirs();
files[i] = new File(dirs.toString() + "/" + fileName);
}
FileOutputStream fos = null;
try {
fos = new FileOutputStream(files[i]);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedOutputStream bos = new BufferedOutputStream(fos);
for(int j = 0; j < fileLength; j++) {
try {
bos.write(bis.read());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
void send(Intent intent){
Parcelable parcelable = intent.getParcelableExtra("selected_wifi_files");
Parceler parceler = Parcels.unwrap(parcelable);
File[] files = parceler.getSelectedFilesWifi();
ExecutorService sendExecutor = newSingleThreadExecutor();
sendExecutor.submit(new Runnable() {
#Override
public void run() {
If(bos == null){
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
DataOutputStream dos = new DataOutputStream(bos);
BufferedOutputStream bos = null;
try {
bos = new BufferedOutputStream(socket.getOutputStream());
} catch (IOException e) {
e.printStackTrace();
}
DataOutputStream dos = new DataOutputStream(bos);
}
try {
dos.writeInt(files.length);
} catch (IOException e) {
e.printStackTrace();
}
for(File file : files)
{
long length = file.length();
try {
dos.writeLong(length);
} catch (IOException e) {
e.printStackTrace();
}
String fileType = FilenameUtils.getExtension(String.valueOf(file));
try {
dos.writeUTF(fileType);
} catch (IOException e) {
e.printStackTrace();
}
String name = file.getName();
try {
dos.writeUTF(name);
} catch (IOException e) {
e.printStackTrace();
}
FileInputStream fis = null;
try {
fis = new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
BufferedInputStream bis = new BufferedInputStream(fis);
int theByte = 0;
while(true) {
try {
if (!((theByte = bis.read()) != -1)) break;
} catch (IOException e) {
e.printStackTrace();
}
try {
bos.write(theByte);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
});
}
I want to transfer a file on Socket connection using Wi-Fi Hotspot IP address and MAC address between two android devices.I am able to transfer a text file with less than 1 KB size but unable to send other extension files and of bigger size using socket. Below is the code for Sender side:-
Socket socket = null;
File file = new File(
Environment.getExternalStorageDirectory(),
"test.mp3");
byte[] bytes = new byte[(int) file.length()];
BufferedInputStream bis;
try {
socket = new Socket(dstAddress, dstPort);
bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytes, 0, bytes.length);
OutputStream os = socket.getOutputStream();
os.write(bytes, 0, bytes.length);
os.flush();
if (socket != null) {
socket.close();
}
final String sentMsg = "File Sent.....";
((Activity)context_con).runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(context_con,
sentMsg,
Toast.LENGTH_LONG).show();
}});
}catch (ConnectException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
if (socket != null) {
socket.close();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This is the code for Receiver End:-
try {
File file = new File(
Environment.getExternalStorageDirectory(),
"test.mp3");
byte[] bytes = new byte[1024];
InputStream is = socket.getInputStream();
FileOutputStream fos = new FileOutputStream(file);
BufferedOutputStream bos = new BufferedOutputStream(fos);
int bytesRead = is.read(bytes, 0, bytes.length);
bos.write(bytes, 0, bytesRead);
bos.close();
socket.close();
final String sentMsg = "File Received...";
Main.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(Main.this,
sentMsg,
Toast.LENGTH_LONG).show();
}});
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I want to transfer bigger size files like mp3 file but it only creating 1Kb size file on receiver end not with the exact size which is 2.1 MB. Please help me where I am wrong in this implementation.
Put together this but haven't tested it. This should give some hints
//Server side snippet
public void server(int port) throws IOException {
try (ServerSocket serverSocket = new ServerSocket(port); Socket socket = serverSocket.accept()) {
try (InputStream in = socket.getInputStream(); OutputStream out = new FileOutputStream("test.mp3")) {
byte[] bytes = new byte[2 * 1024];
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
}
}
}
//client side
public static void client(String dstAddress, int dstPort) throws IOException {
try (Socket socket = new Socket(dstAddress, dstPort)) {
File file = new File(Environment.getExternalStorageDirectory(), "test.mp3");
// Get the size of the file
long length = file.length();
if (length > 0) {
byte[] bytes = new byte[2 * 1024];
InputStream in = new FileInputStream(file);
OutputStream out = socket.getOutputStream();
int count;
while ((count = in.read(bytes)) > 0) {
out.write(bytes, 0, count);
}
out.close();
in.close();
}
}
}
You could choose to wrap the resources with try-catch as i've done or you can choose not to. Consider adjusting the buffer size accordingly. Consider this
Please try that.
I am using RetrieveFilestream method with BufferedInputStream in a for loop. I am closing all
streams after processing each file and also adding ftp complete pending command.
Every thing works as expected in my test environment with few files. But in realtime data where there are 200-300 files, it hangs somewhere.
It is not throwing any exception making it difficult to debug. Cannot debug one by one. Any help?
Here is my code Block.
public String LoopThroughFiles(FTPClient myftp, String DirectoryName)
{
boolean flag=false;
String output="";
InputStream inStream=null;
BufferedInputStream bInf= null;
StringBuilder mystring = new StringBuilder();
progressBar = (ProgressBar) findViewById(R.id.progressBar);
try {
flag= myftp.changeWorkingDirectory(DirectoryName);
if(flag==true)
{
FTPFile[] files = myftp.listFiles();
progressBar.setMax(files.length);
String fname="";
myftp.enterLocalPassiveMode();
if(files.length > 0)
{
int n=0;
for (FTPFile file : files)
{
n=n+1;
int r= progressBar.getProgress();
progressBar.setProgress(r+n);
fname=file.getName();
// String path= myftp.printWorkingDirectory();
if(fname.indexOf("txt") != -1)
{
inStream = myftp.retrieveFileStream(fname);
int reply = myftp.getReplyCode();
if (inStream == null || (!FTPReply.isPositivePreliminary(reply) && !FTPReply.isPositiveCompletion(reply))) {Log.e("error retrieving file",myftp.getReplyString()); }
bInf=new BufferedInputStream (inStream);
int bytesRead;
byte[] buffer=new byte[1024];
String fileContent=null;
while((bytesRead=bInf.read(buffer))!=-1)
{
fileContent=new String(buffer,0,bytesRead);
mystring.append(fileContent);
}
mystring.append(",");
bInf.close();
inStream.close();
boolean isSucess= myftp.completePendingCommand();
if(isSucess == false)
Log.e("error retrieving file","Failed to retrieve the stream for " + fname);
}
}
flag= myftp.changeToParentDirectory();
}
}
}
catch (java.net.UnknownHostException e) {
e.printStackTrace();
Log.e("readfile,UnknownHost",e.getMessage());
}
catch (java.io.IOException e) {
e.printStackTrace();
Log.e("readfile,IO",e.getMessage());
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("readfile,General",e.getMessage());
}
finally
{
try {
output = mystring.toString();
if(bInf != null)
bInf.close();
if(inStream != null)
inStream.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("readfile,finallyblock",e.getMessage());
}
}
return output;
}
I have created a small server client program for Android. It is working like charm except one thing. First session of file transfer works without any problem, but when I try to send another file, I can't do it without restarting my socket connection. I wanted to achieve this:
1. Start Android server
2. Connect remote client
3. Transfer as many files as one wishes in the same session (without having to restart server and reconnecting client)
How can it be done? Any help would be appreciated!
Here's my code snippet:
Server side methods:
public void initializeServer() {
try {
serverSocket = new ServerSocket(4444);
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Server started successfully at: "+ getLocalIpAddress());
registerLog("Listening on port: 4444");
registerLog("Waiting for client request . . .");
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("Listen failed", "Couldn't listen to port 4444");
}
try {
socket = serverSocket.accept();
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Client connected: "+socket.getInetAddress());
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("Acceptance failed", "Couldn't accept client socket connection");
}
}
Sending file to client:
public void sendFileDOS() throws FileNotFoundException {
runOnUiThread( new Runnable() {
#Override
public void run() {
registerLog("Sending. . . Please wait. . .");
}
});
final long startTime = System.currentTimeMillis();
final File myFile= new File(filePath); //sdcard/DCIM.JPG
byte[] mybytearray = new byte[(int) myFile.length()];
FileInputStream fis = new FileInputStream(myFile);
BufferedInputStream bis = new BufferedInputStream(fis);
DataInputStream dis = new DataInputStream(bis);
try {
dis.readFully(mybytearray, 0, mybytearray.length);
OutputStream os = socket.getOutputStream();
//Sending file name and file size to the server
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF(myFile.getName());
dos.writeLong(mybytearray.length);
dos.write(mybytearray, 0, mybytearray.length);
dos.flush();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
runOnUiThread( new Runnable() {
#Override
public void run() {
long estimatedTime = (System.currentTimeMillis() - startTime)/1000;
registerLog("File successfully sent");
registerLog("File size: "+myFile.length()/1000+" KBytes");
registerLog("Elapsed time: "+estimatedTime+" sec. (approx)");
registerLog("Server stopped. Please restart for another session.");
}
});
}
Client side (running on PC):
public class myFileClient {
final static String servAdd="10.142.198.127";
static String filename=null;
static Socket socket = null;
static Boolean flag=true;
/**
* #param args
*/
public static void main(String[] args) throws IOException {
// TODO Auto-generated method stub
initializeClient();
receiveDOS();
}
public static void initializeClient () throws IOException {
InetAddress serverIP=InetAddress.getByName(servAdd);
socket=new Socket(serverIP, 4444);
}
public static void receiveDOS() {
int bytesRead;
InputStream in;
int bufferSize=0;
try {
bufferSize=socket.getReceiveBufferSize();
in=socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
String fileName = clientData.readUTF();
System.out.println(fileName);
OutputStream output = new FileOutputStream("//home//evinish//Documents//Android//Received files//"+ fileName);
long size = clientData.readLong();
byte[] buffer = new byte[bufferSize];
while (size > 0
&& (bytesRead = clientData.read(buffer, 0,
(int) Math.min(buffer.length, size))) != -1) {
output.write(buffer, 0, bytesRead);
size -= bytesRead;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Try flushing just after
output.write(buffer, 0, bytesRead);
If this still doesn't work I found mine server/client works best with objectoutputstreams that you use in the the following way.
oos = new ObjectOutputStream(socket.getOutputStream());
ois = new ObjectInputStream(socket.getInputStream());
// always call flush and reset after sending anything
oos.writeObject(server.getPartyMembersNames());
oos.flush();
oos.reset();
YourObject blah = (YourObject) ois.readObject();
I have this class which connects to a server through sockets, for some reason it is always timing out from here and I can't figure out why, I thought at first it had to do with it being with onCreate(), thats why doit() even exists. any help would be appreciated. here is my code...
public class Ads extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ads);
doit();
};
public void doit(){
Socket socket = null;
FileOutputStream fos = null;
DataInputStream dis = null;
BufferedOutputStream buf = null;
DataOutputStream dos = null;
try {
socket = new Socket("192.168.1.106", 4447);
Bundle extras = getIntent().getExtras();
String value = extras.getString("keyName");
dos = new DataOutputStream(
new BufferedOutputStream(socket.getOutputStream()));
dis = new DataInputStream(new BufferedInputStream(
socket.getInputStream()));
//dos.writeChars(value);
int numFiles = dis.readInt();
File sdCard = Environment.getExternalStorageDirectory();
File dir = new File (sdCard.getAbsolutePath() +value);
dir.mkdirs();
if (dir.isDirectory()) {
String[] children = dir.list();
for (int i=0; i<children.length; i++) {
new File(dir, children[i]).delete();
}
}
int n = 0;
int fileLength = 0;
for (int i=0;i<numFiles;i++){
File file = new File(dir, String.valueOf(i)+".png");
Log.d("debug tag","created file "+file);
}
for (int i=0;i<numFiles;i++){
fileLength = dis.readInt();
byte[] temp = new byte[(int) fileLength];
String path = sdCard.getAbsolutePath()+value+"/"+i+".png";
buf = new BufferedOutputStream(new FileOutputStream(path));
while ((fileLength > 0) && (n = dis.read(temp, 0, (int) Math.min(temp.length, fileLength))) != -1) {
buf.write(temp,0,n);
buf.flush();
fileLength -= n;
}
//buf.close();
Log.d("debug tag","the file is "+temp.length+" bytes long");
}
// now read in text files
n = 0;
fileLength = 0;
for (int i=0;i<numFiles;i++){
File file = new File(dir, String.valueOf(i)+".txt");
Log.d("debug tag","created file "+file);
}
for (int i=0;i<numFiles;i++){
fileLength = dis.readInt();
byte[] temp = new byte[(int) fileLength];
String path = sdCard.getAbsolutePath()+value+"/"+i+".txt";
buf = new BufferedOutputStream(new FileOutputStream(path));
while ((fileLength > 0) && (n = dis.read(temp, 0, (int) Math.min(temp.length, fileLength))) != -1) {
buf.write(temp,0,n);
buf.flush();
fileLength -= n;
}
//buf.close();
Log.d("debug tag","the text file is "+temp.length+" bytes long");
}
generateListView(sdCard.getAbsoluteFile()+value+"/");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
finally{
if (socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (fos != null){
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dis != null){
try {
dis.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if (dos != null){
try {
dos.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
;
I'm afraid the question lacks some important details (it timeouts when connecting, right?), but my blind guess is that your device is using cellular connection, while 192.168.1.106 is on your WiFi network - IPs in the 192.168.x.x pool are private IP addresses, and obviously you can't connect to any such IP address over Internet.
But there's another serious problem with your code - you're trying to make blocking I/O calls in onCreate() - which is executed in the main thread of the application. You should never do this (actually, as soon as you try it on Android 3.x or higher, you'll get NetworkOnMainThreadException). Network I/O should always happen in another thread, either explicitly, or perhaps using AsyncTask (which runs the background thread for you).
For a good introduction, see this post and Designing for Responsiveness guide.