This question already has answers here:
Java multiple file transfer over socket
(3 answers)
Closed 2 years ago.
I am making an app with socket in which i want to share data from two devices in the same wifi. With my code i can share the file successfully between two devices with the exact size of the file and saves into the device storage with a specific name but when i try to open it fails to open in the file manager. I have tried this with mp4 file and apk files
Here is the sender's code
#Override
public void run() {
//File file = new File(src);
File file = new File(Environment.getExternalStorageDirectory() + "/c.mp4");
byte[] bytes = new byte[(int) file.length()];
BufferedInputStream bis;
try {
bis = new BufferedInputStream(new FileInputStream(file));
DataInputStream dis = new DataInputStream(bis);
OutputStream os = socket.getOutputStream();
DataOutputStream dos = new DataOutputStream(os);
dos.writeUTF("anything");
dos.writeLong(bytes.length);
int read;
while ((read = dis.read(bytes)) != -1){
dos.write(bytes,0,read);
}
//os.write(bytes, 0, bytes.length); //commented
//os.flush(); //commented
socket.close();
final String sentMsg = "File sent to: " + socket.getInetAddress();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.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();
}
}
And here is the receiver
#Override
public void run() {
Socket socket = null;
int bytesRead;
InputStream in; //changed
int bufferSize=0;
try {
socket = new Socket(dstAddress, dstPort);
bufferSize = socket.getReceiveBufferSize();
in = socket.getInputStream();
DataInputStream clientData = new DataInputStream(in);
File file = new File(Environment.getExternalStorageDirectory(), "c.mp4");
OutputStream output = new FileOutputStream(file);
byte[] buffer = new byte[bufferSize];
int read;
while ((read = clientData.read(buffer)) != -1){
output.write(buffer, 0 , read);
}
//bos.close(); //commented
socket.close();
MainActivity2.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity2.this, "Finished", Toast.LENGTH_LONG).show();
}});
} catch (IOException e) {
e.printStackTrace();
final String eMsg = "Something wrong: " + e.getMessage();
MainActivity2.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity2.this,
eMsg,
Toast.LENGTH_LONG).show();
}});
} finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
You need to read the clientData (DataInputStream) in the same way you write it to the output stream of the socket.
uft-8 string,
long value,
seq. of bytes
Your mp4 file content will prefixed with "anything" and length. so it will be considered as corrupted file.
save the file without ("anything" and length)
Related
i am trying to send any text or image/audio file over bluetooth using RFCOM server socket.i used the following code
send.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
checkBTPermissions();
// byte[] bytes = etSend.getText().toString().getBytes(Charset.defaultCharset());
// mBluetoothConnection.write(bytes);
file_permission();
// byte[] bytes = etSend.getText().toString().getBytes(Charset.defaultCharset());
File myfile = new File("/sdcard/bluetooth/tom.txt");
byte[] bytes= new byte[(int)myfile.length()];
Log.d(TAG,"file length() =" + (int)myfile.length());
try {
FileInputStream fis = new FileInputStream(myfile);
BufferedInputStream bis = new BufferedInputStream(fis,(int)myfile.length());
//bis.read(bytes,0,bytes.length);
Log.d(TAG,"fis created");
// FileInputStream
mBluetoothConnection.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
});
here i am able to send the contents of my text file and even able to receive.
receiver code:
public void run(){
byte[] buffer = new byte[1024]; // buffer store for the stream
int bytes; // bytes returned from read()
// Keep listening to the InputStream until an exception occurs
while (true) {
// Read from the InputStream
try {
bytes = mmInStream.read(buffer);
String incomingMessage = new String(buffer, 0, bytes);
Log.d(TAG, "InputStream: " + incomingMessage);
} catch (IOException e) {
Log.e(TAG, "write: Error reading Input Stream. " + e.getMessage() );
break;
}
}
}
My question how i can send my file as a whole to the receiver and receive it and save it ?.Among various tutorials i only find how to send text over bluetooth. please help.
This question already has an answer here:
java.net.SocketException socket is closed
(1 answer)
Closed 5 years ago.
I have a application to connect 2 device using socket. In Client, i try send and receive data. When i send data from Client, the Server can receive data and reply a other message. But when i open InputStream to catch receive from server, it show notify (IOException: java.net.SocketException: Socket is closed).
Please help me. ##
CODE IN CLIENT:
Socket socket = null;
String mes = message;
try {
socket = new Socket(dstAddress, dstPort);
/*Example send data to server*/
ops = socket.getOutputStream();
ps = new PrintStream(ops);
ps.print(mes);
ps.close();
/*End of example*/
/*Receive data from server*/
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(
1024);
byte[] buffer = new byte[1024];
int bytesRead;
InputStream inputStream = socket.getInputStream();
while ((bytesRead = inputStream.read(buffer)) != -1) {
byteArrayOutputStream.write(buffer, 0, bytesRead);
response += byteArrayOutputStream.toString("UTF-8");
}
/*End of Receive data from server*/
Log.e("Receive From Server:", response);
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "UnknownHostException: " + e.toString();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
response = "IOException: " + e.toString();
} finally {
if (socket != null) {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
AND THIS CODE OF SERVER
private class SocketServerThread extends Thread {
int count = 0;
#Override
public void run() {
try {
serverSocket = new ServerSocket(socketServerPORT);
while (true) {
Socket socket = serverSocket.accept();
count++;
/*example get input String*/
try {
isr = new InputStreamReader(socket.getInputStream());
br = new BufferedReader(isr);
request = br.readLine();
Log.e("Mess-H.a", request);
}catch (Exception e){
Log.e("Can't receive data:", e.getMessage() );
}
message += "#" + count + " from "
+ socket.getInetAddress() + ":"
+ socket.getPort() + request + "\n";
/*End of example*/
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
SocketServerReplyThread socketServerReplyThread = new SocketServerReplyThread(
socket, count);
socketServerReplyThread.run();
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private class SocketServerReplyThread extends Thread {
private Socket hostThreadSocket;
int cnt;
SocketServerReplyThread(Socket socket, int c) {
hostThreadSocket = socket;
cnt = c;
}
#Override
public void run() {
OutputStream outputStream;
String msgReply = "Hello from Server, you are #" + cnt;
try {
outputStream = hostThreadSocket.getOutputStream();
PrintStream printStream = new PrintStream(outputStream);
printStream.print(msgReply);
printStream.close();
message += "replayed: " + msgReply + "\n";
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
message += "Something wrong! " + e.toString() + "\n";
}
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
activity.msg.setText(message);
}
});
}
}
You closed the socket and then continued to use it.
ps.close();
Here. Remove.
I am using socket to send image from server to multiple client but after sending one image to every client again when i try to send another image it say socket is close but i didn't even close the socket as well.
So i want to keep my server and client socket is alive until the activity is visible.
I am using service to run socket server after that i am getting all socket list to activity so below is my code for server side
if (mSocketArraylist != null) {
for (int i = 0; i < mSocketArraylist.size(); i++) {
Socket mSocket = mSocketArraylist.get(i);
try {
DataOutputStream out = new DataOutputStream(mSocket.getOutputStream());
ContentResolver cr = mContext.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(data.getData().toString()));
} catch (FileNotFoundException e) {
Log.d(TAG, e.toString());
}
copyFile(is, out);
} catch (IOException e) {
e.printStackTrace();
}
}
} else {
Log.e("Socket value", "Socket is null");
}
For client also i am using service below its implementation
class clientThread implements Runnable {
#Override
public void run() {
if (wifiInfo != null) {
if (!wifiInfo.isGroupOwner) {
String host = wifiInfo.groupOwnerAddress.getHostAddress();
Socket clientSocket = new Socket();
OutputStream os = null;
try {
clientSocket.bind(null);
clientSocket.setKeepAlive(true);
clientSocket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
os = clientSocket.getOutputStream();
PrintWriter pw = new PrintWriter(os);
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ SocketClientService.this.getPackageName() + "/VR-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
while (true) {
Log.d(TAG, "server: copying files " + f.toString());
InputStream inputstream = clientSocket.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
break;
}
signalActivity(f.getAbsolutePath());
} catch (IOException e) {
Log.e(TAG, e.getMessage());
} catch (Exception e) {
Log.e(TAG, e.getMessage());
}
} else {
Log.e(TAG, "This device is a group owner, therefore the IP address of the " +
"target device cannot be determined. File transfer cannot continue");
}
}
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[8192 * 8192];
int len;
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
} catch (IOException e) {
Log.d(TAG, e.toString());
return false;
}
return true;
}
So any one can help me out in this , help would be appreciated.
signalActivity method implementation
public void signalActivity(String message) {
Bundle b = new Bundle();
b.putString("message", message);
clientResult.send(port, b);
}
I have written this code to transfer file from server to client, but i am able to send only less than 1 Kb size of file. i want to send any size of file. It would be very helpful if you could modify my code:
File Sender(Server code)
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
infoIp = (TextView) findViewById(R.id.infoip);
infoPort = (TextView) findViewById(R.id.infoport);
infoIp.setText(getIpAddress());
serverSocketThread = new ServerSocketThread();
serverSocketThread.start();
}
#Override
protected void onDestroy() {
super.onDestroy();
if (serverSocket != null) {
try {
serverSocket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
private String getIpAddress() {
String ip = "";
try {
Enumeration<NetworkInterface> enumNetworkInterfaces = NetworkInterface.getNetworkInterfaces();
while (enumNetworkInterfaces.hasMoreElements()) {
NetworkInterface networkInterface = enumNetworkInterfaces.nextElement();
Enumeration<InetAddress> enumInetAddress = networkInterface.getInetAddresses();
while (enumInetAddress.hasMoreElements()) {
InetAddress inetAddress = enumInetAddress.nextElement();
if (inetAddress.isSiteLocalAddress()) {
ip += "SiteLocalAddress: "+ inetAddress.getHostAddress() + "\n";
}
}
}
} catch (SocketException e) {
// TODO Auto-generated catch block
e.printStackTrace();
ip += "Something Wrong! " + e.toString() + "\n";
}
return ip;
}
public class ServerSocketThread extends Thread {
#Override
public void run() {
Socket socket = null;
try {
serverSocket = new ServerSocket(SocketServerPORT);
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
infoPort.setText("I'm waiting here: "
+ serverSocket.getLocalPort());
}});
while (true) {
socket = serverSocket.accept();
FileTxThread fileTxThread = new FileTxThread(socket);
fileTxThread.start();
}
} 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();
}
}
}
}
}
public class FileTxThread extends Thread {
Socket socket;
FileTxThread(Socket socket){
this.socket= socket;
}
#Override
public void run() {
File file = new File(Environment.getExternalStorageDirectory(),"test.mp3");
byte[] bytes = new byte[(int) file.length()];
BufferedInputStream bis;
try {
bis = new BufferedInputStream(new FileInputStream(file));
bis.read(bytes, 0, bytes.length);
OutputStream os = socket.getOutputStream();
os.write(bytes, 0, bytes.length);
os.flush();
// socket.close();
final String sentMsg = "File sent to: " + socket.getInetAddress();
System.out.println("socket getIntentAddress "+socket.getInetAddress());
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this,sentMsg,Toast.LENGTH_LONG).show();
}});
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Ioexception"+e);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
System.out.println("Ioexception"+e);
}
File Receiver(Client Code)
buttonConnect.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
ClientRxThread clientRxThread =
new ClientRxThread(editTextAddress.getText().toString(),SocketServerPORT);
clientRxThread.start();
}});
}
private class ClientRxThread extends Thread {
String dstAddress;
int dstPort;
ClientRxThread(String address, int port) {
dstAddress = address;
dstPort = port;
}
#Override
public void run() {
Socket socket = null;
try {
socket = new Socket(dstAddress, dstPort);
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();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this,"Finished",Toast.LENGTH_LONG).show();
}});
} catch (IOException e) {
e.printStackTrace();
final String eMsg = "Something wrong: " + e.getMessage();
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this,eMsg,Toast.LENGTH_LONG).show();
System.out.println("run"+eMsg);
}});
} finally {
if(socket != null){
try {
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Please help Sir! Thanks in advance!
You need to put the receiving of the bytes in a loop that only completes when all the data has been received. For example:-
byte[] bytes = new byte[1024];
InputStream is = socket.getInputStream();
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file));
while (true) {
int bytesRead = is.read(bytes);
if (bytesRead < 0) break;
bos.write(bytes, 0, bytesRead);
// Now it loops around to read some more.
}
bos.close();
I could have sworn your original questions was about receiving, not sending (and other answers seem to suggest the same).
Regardless, to send large files, you can either read your entire file into a buffer large enough to hold it (assuming the file is of a reasonable size), or use a loop to read it in chunks of a manageable size and then process (send) the chunks.
In answer to your original question, you are only reading 1024 because that is all you are attempting to read. You have allocated your buffer at 1024 and only reading once.
byte[] bytes = new byte[1024];
...
int bytesRead = is.read(bytes, 0, bytes.length);
bos.write(bytes, 0, bytesRead);
bos.close();
try
byte[] bytes = new bytes[1024];
...
int bytesRead = is.read(bytes, 0, bytes.length);
while(bytesRead > 0) {
bos.write(bytes, 0, bytesRead);
bytesRead = is.read(bytes, 0, bytes.length);
}
...
and wrap your code at an appropriate spot with a try/catch block in case of an exception.
I'm downloading a file that is stored on a remote server, I try to decrypt it using JNCryptor, and all goes well except that the file I have downloaded and store in the phone external storage is corrupted and I cannot open it. Can anyone tell me where im going wrong?
Im trying to get the InputStream from the file, decrypt it, and save the file on external storage.
Thanks
Here is my code:
private void downloadFile() {
final String FILE_URL = "https://www.google.com";
final String PASS = "password";
new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... voids) {
Log.d(TAG, "starting");
JNCryptor cryptor = new AES256JNCryptor();
int count;
try {
URL url = new URL(FILE_URL);
URLConnection conection = url.openConnection();
conection.connect();
// this will be useful so that you can show a tipical 0-100%
// progress bar
int lenghtOfFile = conection.getContentLength();
// download the file
InputStream input = new BufferedInputStream(url.openStream(),
8192);
//decrypt istream
byte[] b = null;
byte[] data = null;
try {
b = new byte[input.available()];
input.read(b);
} catch (IOException e) {
Log.i("decrypt error", e.toString());
}
AES256JNCryptorOutputStream cryptorStream = null;
ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
try {
cryptorStream = new AES256JNCryptorOutputStream(byteStream,
PASS.toCharArray());
} catch (CryptorException e) {
e.printStackTrace();
}
try {
cryptorStream.write(b);
cryptorStream.flush();
cryptorStream.close();
} catch (IOException e1) {
e1.printStackTrace();
}
byte[] encrypted = byteStream.toByteArray();
try {
data = cryptor.decryptData(encrypted, PASS.toCharArray());
Log.d(TAG, "decrypted");
} catch (InvalidHMACException e) {
e.printStackTrace();
} catch (CryptorException e) {
e.printStackTrace();
}
if (data != null) {
Log.d(TAG, "data is ok");
}
//end decryption
// Output stream
//test
FileOutputStream fos = new FileOutputStream(Environment
.getExternalStorageDirectory().toString()
+ "/temp.zip");
fos.write(data);
fos.close();
Log.d(TAG, "file saved ");
input.close();
Log.d(TAG, "done");
} catch (Exception e) {
Log.d(TAG, "Error: " + e.getMessage());
}
return null;
}
}.execute();
}
P.S. Im not getting any error or warning in logCat.