文件传输 - Java 套接字编程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20947166/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
File transfer - Java socket programming
提问by Gabriel
I have the following Server and Client codes. Client tries to transfer a File say "testprgm.txt" of Size say 2000B to Server, where it saves it as "Test.txt". The problem is I can see the transfer for bytes on both the Server and Client but when I see the size of the Test.txt file after running these codes, it is ZERO.
我有以下服务器和客户端代码。客户端尝试将大小为 2000B 的文件(例如“testprgm.txt”)传输到服务器,然后将其保存为“Test.txt”。问题是我可以看到服务器和客户端上的字节传输,但是当我在运行这些代码后看到 Test.txt 文件的大小时,它是零。
Server Program:
服务器程序:
import java.io.*;
import java.net.*;
public class ServerTest {
public static void main(String[] args) {
System.out.println("**********Server Program**************");
int byteRead = 0;
try {
ServerSocket serverSocket = new ServerSocket(9999);
if (!serverSocket.isBound())
System.out.println("Sever Socket not Bounded...");
else
System.out.println("Server Socket bounded to Port : " + serverSocket.getLocalPort());
Socket clientSocket = serverSocket.accept();
if (!clientSocket.isConnected())
System.out.println("Client Socket not Connected...");
else
System.out.println("Client Socket Connected : " + clientSocket.getInetAddress());
while (true) {
InputStream in = clientSocket.getInputStream();
OutputStream os = new FileOutputStream("<DESTINATION PATH>/Test.txt");
byte[] byteArray = new byte[100];
while ((byteRead = in .read(byteArray, 0, byteArray.length)) != -1) {
os.write(byteArray, 0, byteRead);
System.out.println("No. of Bytes Received : " + byteRead);
}
synchronized(os) {
os.wait(100);
}
os.close();
serverSocket.close();
//System.out.println("File Received...");
}
} catch (Exception e) {
System.out.println("Server Exception : " + e.getMessage());
e.printStackTrace();
}
}
}
Client Program :
客户计划:
import java.io.*;
import java.net.*;
public class Clientprgm {
public static void main(String[] args)
{
Socket socket;
try
{
socket = new Socket("SERVER IP ADDRESS>", 9999);
if(!socket.isConnected())
System.out.println("Socket Connection Not established");
else
System.out.println("Socket Connection established : "+socket.getInetAddress());
File myfile = new File("<SOURCE PATH>/testprgm.txt"); //local file path.
if(!myfile.exists())
System.out.println("File Not Existing.");
else
System.out.println("File Existing.");
byte[] byteArray = new byte[1024];
FileInputStream fis = new FileInputStream(myfile);
BufferedInputStream bis = new BufferedInputStream(fis);
OutputStream os = socket.getOutputStream();
int trxBytes =0;
while((trxBytes = bis.read(byteArray, 0, byteArray.length)) !=-1)
{
os.write(byteArray, 0, byteArray.length);
System.out.println("Transfering bytes : "+trxBytes );
}
os.flush();
bis.close();
socket.close();
System.out.println("File Transfered...");
}
catch(Exception e)
{
System.out.println("Client Exception : "+e.getMessage());
}
}
}
采纳答案by user207421
Your server copy loop is correct, in that it uses the count returned by read()
in the write()
method call. Your client copy loop should do the same. It doesn't.
您的服务器副本循环是正确的,因为它使用返回的计数read()
的write()
方法调用。您的客户端复制循环也应该这样做。它没有。
In any case your protocol is based on a fallacy. read()
on a socket input stream will return -1 when the peer closes the connection, and not before. So putting a loop that terminates when read()
returns -1 inside another loop using the same connection cannot possibly work. It seems you are trying to send multiple files over a single connection. You need to send the length ahead of each file, and only read exactly that many bytes per file.
在任何情况下,您的协议都是基于谬论。read()
当对等方关闭连接时,套接字输入流将返回 -1,而不是之前。因此,将一个在read()
返回 -1时终止的循环放入另一个使用相同连接的循环中是不可能的。您似乎正在尝试通过单个连接发送多个文件。您需要在每个文件之前发送长度,并且每个文件只读取那么多字节。
Or else you need to close the connection after sending a single file, and remove the outer loop in the receiver.
否则,您需要在发送单个文件后关闭连接,并删除接收器中的外循环。
回答by Evgeniy Dorofeev
I would use NIO for file transfer it's shorter and more efficient. Here's client side:
我会使用 NIO 进行文件传输,它更短、更高效。这是客户端:
try (SocketChannel sc = SocketChannel.open(new InetSocketAddress(
hostaddress, 9999));
FileChannel fc = new FileInputStream("test").getChannel()) {
fc.transferTo(0, fc.size(), sc);
}
System.out.println("File Transfered...");
Server side:
服务器端:
ServerSocketChannel ss = ServerSocketChannel.open();
ss.bind(new InetSocketAddress("localhost", 9999));
try (SocketChannel sc = ss.accept();
FileChannel fc = new FileOutputStream("test").getChannel()) {
fc.transferFrom(sc, 0, Long.MAX_VALUE);
}