如何在Android中使用套接字发送大文件
我已经编写了此代码以便将文件从服务器传输到客户端,但我只能发送小于1 Kb的文件大小。我想发送任何大小的文件。这将是非常有益的,如果你可以修改我的代码:如何在Android中使用套接字发送大文件
文件发送方(Server代码)
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);
}
文件接收方(客户端代码)
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();
}
请帮助爵士!提前致谢!
我可以发誓你的原始问题是关于接收,而不是发送(和其他答案似乎表明相同)。无论如何,要发送大文件,您可以将整个文件读入一个足够大的缓冲区(假定该文件的大小合理),或者使用循环以可管理大小的块读取它然后处理(发送)块。
回答您的原始问题,您只读取1024,因为这是您正在尝试阅读的所有内容。你已经在1024分配了你的缓冲区,只能读一次。
byte[] bytes = new byte[1024];
...
int bytesRead = is.read(bytes, 0, bytes.length);
bos.write(bytes, 0, bytesRead);
bos.close();
尝试
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);
}
...
,并在同一个异常的情况下,try/catch块中的适当位置包裹你的代码。
您需要将接收的字节放入一个循环中,该循环只有在接收到所有数据时才会完成。例如: -
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();
请确保你在服务或线程中使用它,因为活动可能在任何时候被终止。前台服务保持活动状态。如果你想在后台服务中处理这个问题,请确保你保存了“状态”,然后继续运行。服务返回 –
你是否尝试过单步执行IDE中的代码? –
使用此代码我发送55mb大小的文件正确。但是当我试图传输500MB大小的文件,然后它显示错误 - 抛出OutOfMemoryError“未能分配360318346字节分配5802592空闲字节和87MB,直到OOM”和应用程序自动崩溃System.err:java.net.SocketException:套接字关闭 谢谢。 –
如果您尝试发送更大的文件,会发生什么情况?你有什么错误吗? –
数据仅传输1kb大小的文件,但我想传输大文件。请帮助我,如果有任何解决方案。谢谢你 –
看到我的答案。您的客户没有读取所有可用数据。 –