你好,我试图在java中使用客户端 - 服务器类发送文件。出于某种原因,当调用发送文件的方法时,套接字关闭。这是代码:
FileInputStream fIn = new FileInputStream(file);
out = new BufferedOutputStream(clientSocket.getOutputStream());
byte fileContent[] = new byte[(int) file.length()];
fIn.read(fileContent);
for (byte b : fileContent) {
out.write(b);
}
以及来自客户端的代码:
FileOutputStream fIn = new FileOutputStream("testing");
BufferedInputStream inAout = new BufferedInputStream(clientSocket.getInputStream());
byte fileContent[] = new byte[1000000];
inAout.read(fileContent);
fIn.write(fileContent);
并收到错误消息:SEVERE:null java.net.SocketException:Socket关闭
我对此并不是很有经验,所以如果有任何可以帮助它会很棒。
答案 0 :(得分:14)
InputStream.read(byte[])
方法返回int
表示它实际读取的字节数。不能保证读取字节数组中请求的字节数。它通常会返回底层缓冲区的大小,你必须多次调用它。
通过将字节从套接字流式传输到文件而不是缓冲内存中的整个字节数组,可以更有效地使用它。同样在服务器端,你可以做同样的事情来节省内存,并且比一次写一个字节更快。
这是一个服务器和客户端的工作示例,它连接到自身以传输文件:
public class SocketFileExample {
static void server() throws IOException {
ServerSocket ss = new ServerSocket(3434);
Socket socket = ss.accept();
InputStream in = new FileInputStream("send.jpg");
OutputStream out = socket.getOutputStream();
copy(in, out);
out.close();
in.close();
}
static void client() throws IOException {
Socket socket = new Socket("localhost", 3434);
InputStream in = socket.getInputStream();
OutputStream out = new FileOutputStream("recv.jpg");
copy(in, out);
out.close();
in.close();
}
static void copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[8192];
int len = 0;
while ((len = in.read(buf)) != -1) {
out.write(buf, 0, len);
}
}
public static void main(String[] args) throws IOException {
new Thread() {
public void run() {
try {
server();
} catch (IOException e) {
e.printStackTrace();
}
}
}.start();
client();
}
}
答案 1 :(得分:0)
原因很简单:在传输了大约4KB的数据后,调用inAout.read(fileContent)
将返回。那是输入缓冲区大小。因此,与套接字相比,您需要一个循环,并且需要多次读取和写入fIn
的字节。
另外不要忘记刷新服务器端的输出(关闭会刷新它)或者某些数据会丢失。
答案 2 :(得分:0)
SEVERE: null java.net.SocketException: Socket closed
这意味着您已经自己关闭了套接字,然后调用了另一个需要打开它的操作。例如,关闭套接字或其输入流或输出流将关闭另一个流和套接字。某处或其他地方,你正在这样做。