gpt4 book ai didi

java - Java socket编程如何实现客户端到服务器的持续交互

转载 作者:行者123 更新时间:2023-11-30 09:17:18 25 4
gpt4 key购买 nike

如何在 Java 套接字编程中实现从客户端到服务器的连续交互。在我的程序中,我在一个目录中有很多文件夹,即)F://read,我正在将带有文件的文件夹从客户端传输到服务器。当第一次请求时,一个文件夹从客户端传输到服务器,当它再次发送到客户端发送另一个文件夹时,它一直在说异常,java.net.SocketException:套接字在 ClientProgram 的 write() 方法中关闭,其中我调用 socket.getOutputStream()。所以请告诉我如何解决这个问题。我想我想为每个传输使用线程,所以请告诉我必须在哪里运行才能正常运行。非常感谢。

客户端代码:

每次转发方法和写入方法将数据从客户端传递到服务器。和 listf(String directoryName) 方法对文件和文件夹递归运行,当它找到文件夹时调用 forward() 和 write() 方法。 forward() 是传递特定文件夹的目录路径,而 write() 方法是将所有文件写入客户端,并每次通过 listf(String directoryName) 传递给服务器。第一次这种方法运行良好。当它第二次再次调用 write() 方法时,它给出了 java.net.SocketException: Socket is closed.why its happening.

import java.io.*;
import java.net.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.ListIterator;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ClientProgram extends HttpServlet {

private static final long serialVersionUID = 1L;

public ClientProgram() {
super();
}
Socket socket;
ClientProgram clientProgram;
String hostDomain = "192.168.1.19";
int port = 5855;
BufferedOutputStream bos;
DataOutputStream dos;
BufferedInputStream bis;
FileInputStream fis;
PrintStream pr;
BufferedReader gt;
List<File> resultList;

public static listf(String directoryName) throws IOException {
try {
File directory = new File(directoryName);
resultList = new ArrayList<File>();
// get all the files from a directory
File[] fList = directory.listFiles();
resultList.addAll(Arrays.asList(fList));
for (File file : fList) {
if (file.isFile()) {
System.out.println("file: " + file.getAbsolutePath());
} else if (file.isDirectory()) {
String pathtomake = file.getAbsolutePath();
System.out.println("folder now: " + pathtomake);
forward(pathtomake);
write(pathtomake);
System.out.println("folder: " + file.getAbsolutePath());
listf(file.getAbsolutePath());

}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bis != null) {
bis.close();
}
if (dos != null) {
dos.close();
}
if (fis != null) {
fis.close();
}
}
return resultList;
}

public void write(String rec) throws IOException {
try {
System.out.println("rr");
bos = new BufferedOutputStream(socket.getOutputStream());
dos = new DataOutputStream(bos);
File file1 = new File(rec);
File[] fil_Files_list = file1.listFiles();
dos.writeInt(fil_Files_list.length);
System.out.println("file will ..");
for (File file : fil_Files_list) {
long length = file.length();
dos.writeLong(length);
String name = file.getName();
dos.writeUTF(name);
fis = new FileInputStream(file);
bis = new BufferedInputStream(fis);
System.out.println("writin..");
int theByte = 0;
while ((theByte = bis.read()) != -1) {
bos.write(theByte);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
}
}

public void forward(String drc) throws UnknownHostException, IOException {
boolean b = socket.isConnected();
System.out.println("Socket Is active or not: " + b);
pr = new PrintStream(socket.getOutputStream());
pr.println(drc);
gt = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String tm = gt.readLine();
System.out.print(tm);
}

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
socket = new Socket(hostDomain, port);
String directory = "F://read";
listf(directory);

}

}

服务器代码:

这是我的服务器代码,用于接收包含文件的文件夹。在这里,我使用 BufferedReader 从名为 forward() 的客户端方法接收文件夹路径,并添加到目标路径 ie)d://save。之后,我通过名为 write() 的客户端方法将所有文件写入特定文件夹。

import java.io.*;
import java.net.*;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class ServerProgram extends HttpServlet {

private static final long serialVersionUID = 1L;

public ServerProgram() {
super();
// TODO Auto-generated constructor stub
}

BufferedReader ed;
PrintStream pr;
BufferedInputStream bis;
DataInputStream dis;
FileOutputStream fos;
BufferedOutputStream bos;
Socket socket;

protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
try {
System.out.println(1);
ServerSocket serverSocket = new ServerSocket(5792);
System.out.println(2);
socket = serverSocket.accept();

ed = new BufferedReader(new InputStreamReader(socket.getInputStream()));
String tmp = ed.readLine();
System.out.print("I Recieved :" + tmp);
pr = new PrintStream(socket.getOutputStream());
String str = "Yup I got it !!";
pr.println(str);
int g = tmp.indexOf("\\");
String di = tmp.substring(g);
String dirPath = "D://save//" + di;
System.out.println(dirPath);
File file = new File(dirPath);
JavaHeapMemory();

if (file.exists() || file.mkdirs()) {
bis = new BufferedInputStream(socket.getInputStream());
dis = new DataInputStream(bis);
int filesCount = dis.readInt();
File[] files = new File[filesCount];
for (int i = 0; i < filesCount; i++) {
long fileLength = dis.readLong();
String fileName = dis.readUTF();
System.out.println("name of the file: " + fileName);
files[i] = new File(dirPath + "/" + fileName);
FileOutputStream fos = new FileOutputStream(files[i]);
BufferedOutputStream bos = new BufferedOutputStream(fos);
for (int j = 0; j < fileLength; j++) {
bos.write(bis.read());
}

}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (bos != null) {
bos.close();
}
if (dis != null) {
dis.close();
}
try {
socket.close();
} catch (Exception e) {
// TODO: handle exception
}
}
}

public void JavaHeapMemory() {
long heapSize = Runtime.getRuntime().totalMemory();
System.out.println("Heap Size = " + heapSize);
}
}

异常(exception):

            java.net.SocketException: Socket is closed
at java.net.Socket.getOutputStream(Unknown Source)
at pack.ClientProgram.forward()

在上面的客户端程序中,我曾经递归地将文件夹传输到服务器。但它不是从客户端到服务器连续运行。所以请告诉我执行此操作的方法。非常感谢。

最佳答案

您不能混合文本和二进制文件以免造成混淆。

  ed = new BufferedReader(new InputStreamReader(socket.getInputStream()));

这意味着 BufferedReader 可以读取尽可能多的数据,而不仅仅是您要求的数据。

  bis = new BufferedInputStream(socket.getInputStream());

这将在 BufferedReader 未读取的某个随机点开始读取二进制文件(不是您要求的数量)

简而言之,除非您真的知道自己在做什么,否则只对流使用二进制或文本。


你的程序有

while ((theByte = bis.read()) != -1)
bos.write(theByte);

这意味着,读取直到流结束。这也意味着它将读取所有发送的数据,直到连接关闭。

如果你想在同一个流中发送多个文件,你需要另一种方式让接收者知道文件何时结束。最简单的方法是先发送文件大小,然后让接收方只读取那么多的数据。

顺便说一句,一次读取一个字节非常很慢。我建议您读入一个大小为 4KB 的 byte[]。

关于java - Java socket编程如何实现客户端到服务器的持续交互,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19027919/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com