使用套接字 wifip2p 发送文件列表
Send list of files using socket wifip2p
我正在尝试使用套接字将多个文件从客户端发送到服务器,但是当我点击上传按钮时它只添加了一个文件秒
您的copyFile()
不适合网络传输。
您需要删除 copyFile()
中的两个 close()
调用。在客户端,out.close()
在第一个文件发送后关闭套接字。在服务器端,InputStream.close()
在收到第一个文件后关闭套接字。关闭它传递给 copyFile()
的流是调用者的责任,而不是 copyFile()
的责任。
更重要的是,对于客户端要发送的每个文件,copyFile()
在发送文件的实际字节数之前不会发送文件的字节数,以指示每个文件的结束位置和下一个文件的开始位置。因此,在服务器端,copyFile()
不知道什么时候停止从 inputStream
读取数据,只会继续无休止地读取数据,直到连接 closed/broken.
照原样,copyFile()
可能适用于将文件从一个文件夹复制到本地系统上的另一个文件夹,但它不适合通过 TCP 网络复制文件。
试试这个:
客户端:
try {
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.d(TAG, "Client socket - " + socket.isConnected());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(fileUri.size());
for(String file : fileUri)
{
//long length = file.length();
//dos.writeLong(length);
String name = file;
dos.writeUTF(name);
File f = new File(file);
sendFile(f, dos);
}
dos.close();
Log.d(TAG, "Client: Data written");
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
}
catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
void sendFile(File in, DataOutputStream out) throws IOException {
long fileLength = in.length();
out.writeLong(fileLength);
FileInputStream fis = new FileInputStream(in);
BufferedInputStream bis = new BufferedInputStream(fis);
byte buf[] = new byte[1024];
int len;
while (fileLength > 0) {
len = bis.read(buf);
if (len == -1) throw new IOException();
out.write(buf, 0, len);
fileLength -= len;
}
}
服务器端:
try {
ServerSocket serverSocket = new ServerSocket(8988);
Socket client = serverSocket.accept();
BufferedInputStream bis = new BufferedInputStream(client.getInputStream());
DataInputStream dis = new DataInputStream(bis);
int filesCount = dis.readInt();
File[] files = new File[filesCount];
for(int i = 0; i < filesCount; i++)
{
Log.d(TAG, "doInBackground: " + filesCount);
//long fileLength = dis.readLong();
String fileName = dis.readUTF();
files[i] = new File(context.getExternalFilesDir("received"), Long.toString(System.currentTimeMillis()) + ".mp4" );
Log.d(TAG, "doInBackground: 1" );
File dirs = new File(context.getPackageName() + files[i].getParent());
Log.d(TAG, "doInBackground: 2" );
if (!dirs.exists()) dirs.mkdirs();
files[i].createNewFile();
Log.d(TAG, "server: copying files " + files[i].toString());
receiveFile(dis, files[i]);
}
serverSocket.close();
return "done";
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
return null;
}
void receiveFile(DataInputStream in, File out) throws IOException {
long fileLength = in.readLong();
FileOutputStream fos = new FileOutputStream(out);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
int len;
while (fileLength > 0) {
len = (fileLength >= 1024) ? 1024 : (int) fileLength;
len = in.read(buf, 0, len);
if (len == -1) throw new IOException();
bos.write(buf, 0, len);
fileLength -= len;
}
}
我正在尝试使用套接字将多个文件从客户端发送到服务器,但是当我点击上传按钮时它只添加了一个文件秒
您的copyFile()
不适合网络传输。
您需要删除 copyFile()
中的两个 close()
调用。在客户端,out.close()
在第一个文件发送后关闭套接字。在服务器端,InputStream.close()
在收到第一个文件后关闭套接字。关闭它传递给 copyFile()
的流是调用者的责任,而不是 copyFile()
的责任。
更重要的是,对于客户端要发送的每个文件,copyFile()
在发送文件的实际字节数之前不会发送文件的字节数,以指示每个文件的结束位置和下一个文件的开始位置。因此,在服务器端,copyFile()
不知道什么时候停止从 inputStream
读取数据,只会继续无休止地读取数据,直到连接 closed/broken.
照原样,copyFile()
可能适用于将文件从一个文件夹复制到本地系统上的另一个文件夹,但它不适合通过 TCP 网络复制文件。
试试这个:
客户端:
try {
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
Log.d(TAG, "Client socket - " + socket.isConnected());
BufferedOutputStream bos = new BufferedOutputStream(socket.getOutputStream());
DataOutputStream dos = new DataOutputStream(bos);
dos.writeInt(fileUri.size());
for(String file : fileUri)
{
//long length = file.length();
//dos.writeLong(length);
String name = file;
dos.writeUTF(name);
File f = new File(file);
sendFile(f, dos);
}
dos.close();
Log.d(TAG, "Client: Data written");
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
}
finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
}
catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
void sendFile(File in, DataOutputStream out) throws IOException {
long fileLength = in.length();
out.writeLong(fileLength);
FileInputStream fis = new FileInputStream(in);
BufferedInputStream bis = new BufferedInputStream(fis);
byte buf[] = new byte[1024];
int len;
while (fileLength > 0) {
len = bis.read(buf);
if (len == -1) throw new IOException();
out.write(buf, 0, len);
fileLength -= len;
}
}
服务器端:
try {
ServerSocket serverSocket = new ServerSocket(8988);
Socket client = serverSocket.accept();
BufferedInputStream bis = new BufferedInputStream(client.getInputStream());
DataInputStream dis = new DataInputStream(bis);
int filesCount = dis.readInt();
File[] files = new File[filesCount];
for(int i = 0; i < filesCount; i++)
{
Log.d(TAG, "doInBackground: " + filesCount);
//long fileLength = dis.readLong();
String fileName = dis.readUTF();
files[i] = new File(context.getExternalFilesDir("received"), Long.toString(System.currentTimeMillis()) + ".mp4" );
Log.d(TAG, "doInBackground: 1" );
File dirs = new File(context.getPackageName() + files[i].getParent());
Log.d(TAG, "doInBackground: 2" );
if (!dirs.exists()) dirs.mkdirs();
files[i].createNewFile();
Log.d(TAG, "server: copying files " + files[i].toString());
receiveFile(dis, files[i]);
}
serverSocket.close();
return "done";
}
catch (IOException e) {
Log.e(TAG, e.getMessage());
return null;
}
void receiveFile(DataInputStream in, File out) throws IOException {
long fileLength = in.readLong();
FileOutputStream fos = new FileOutputStream(out);
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte buf[] = new byte[1024];
int len;
while (fileLength > 0) {
len = (fileLength >= 1024) ? 1024 : (int) fileLength;
len = in.read(buf, 0, len);
if (len == -1) throw new IOException();
bos.write(buf, 0, len);
fileLength -= len;
}
}