我在使用Java运行这两个线程时遇到了麻烦。我在客户端类中有两个方法,并且在每个方法中它们都有一个不同端口的套接字但是当我运行客户端时,我看到一个线程的瞬间错误,而另一个发送文件的错误
任何帮助?
ClientApp.java
public static void main(String[] args) throws UnknownHostException, IOException, InterruptedException {
Thread getFileThread = new Thread() {
public void run() {
Client client = new Client();
try {
client.getTheFile("girlwithmask.jpg");
} catch (UnknownHostException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
Thread getListOfFilesThread = new Thread() {
public void run() {
Client client = new Client();
ArrayList<String> listOfFiles = null;
try {
listOfFiles = client.getFileList();
System.out.println(listOfFiles.get(1));
notify();
} catch (ClassNotFoundException | IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
getListOfFilesThread.start();
getFileThread.start();
}
Client.java
public class Client {
private static final int PORT = 2665;
private static String HOST = "localhost";
Client() {
}
public void getTheFile(String filename) throws UnknownHostException, IOException {
filename = "girlwithmask.jpg"; ///this is temporary
int filesize = 5000000; //buffer size 5mb
int bytesRead;
int currentTotalNumberOfBytes = 0;
//connect to port on server - server waits for this after running socket.accept() in the Server class
Socket socket = new Socket(HOST, PORT);
byte[] byteArray = new byte[filesize]; //create a byte array of 5mb
InputStream inputStream = socket.getInputStream(); //channel to to server
FileOutputStream fileOutStream = new FileOutputStream("myClientFiles/" + filename);
BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);
bytesRead = inputStream.read(byteArray, 0, byteArray.length);
currentTotalNumberOfBytes = bytesRead;
do { //read till the end and store total in bytesRead and add it to currentTotalNumberOfBytes
bytesRead = inputStream.read(byteArray, currentTotalNumberOfBytes, (byteArray.length - currentTotalNumberOfBytes));
if (bytesRead >= 0) {
currentTotalNumberOfBytes += bytesRead;
}
} while (bytesRead > -1); // when bytesRead == -1, there's no more data left and we exit the loop
bufferOutStream.write(byteArray, 0, currentTotalNumberOfBytes); //write the bytes to the file
bufferOutStream.flush();
bufferOutStream.close();
socket.close();
}
public ArrayList<String> getFileList() throws UnknownHostException, IOException, ClassNotFoundException {
Socket socket = new Socket("localhost", 9999);
ArrayList<String> titleList = new ArrayList<String>();
ObjectInputStream objectInput = new ObjectInputStream(socket.getInputStream());
Object object = objectInput.readObject();
titleList = (ArrayList<String>) object;
// System.out.println(titleList.get(2));
return titleList;
}
}
我不确定这里发生了什么。已经使用了几个小时。
答案 0 :(得分:2)
在没有实际错误或确实存在问题的情况下,我们所能做的就是批评您的代码:
byte[] byteArray = new byte[filesize]; //create a byte array of 5mb
你知道 filesize
是什么。你已经硬编码了50000的 猜测 。这对于任何文件大小超过5000000的情况都不适用。有一种方法,你不需要 来了解文件大小:或首先需要一个大小与整个文件大小相同的缓冲区。您假设文件适合内存并且文件长度适合int.
两种假设都可能是错误的。使用较小的缓冲区大小8192或一些合理的数字,通常是1024的倍数,以获得良好的内存对齐。大码5000000的硬编码有上述缺点。
InputStream inputStream = socket.getInputStream(); //channel to to server
FileOutputStream fileOutStream = new FileOutputStream("myClientFiles/" + filename);
BufferedOutputStream bufferOutStream = new BufferedOutputStream(fileOutStream);
你真的不需要BufferedOutputStream
这个代码,或者至少使用这个代码,但现在就让它通过。
bytesRead = inputStream.read(byteArray, 0, byteArray.length);
currentTotalNumberOfBytes = bytesRead;
do { //read till the end and store total in bytesRead and add it to currentTotalNumberOfBytes
bytesRead = inputStream.read(byteArray, currentTotalNumberOfBytes, (byteArray.length - currentTotalNumberOfBytes));
if (bytesRead >= 0) {
currentTotalNumberOfBytes += bytesRead;
}
} while (bytesRead > -1); // when bytesRead == -1, there's no more data left and we exit the loop
bufferOutStream.write(byteArray, 0, currentTotalNumberOfBytes); //write the bytes to the file
要缩短此代码,您可能需要将其更改为规范格式:
int count;
byte[] buffer = new byte[8192];
while ((count = in.read(buffer)) > 0)
{
out.write(buffer, 0, count);
}
适当地替换变量名称。你会:
拥有经过良好测试的代码,已经运行了18年。
bufferOutStream.flush();
flush()
是多余的。
close()
关闭其输出流(或输入流)后关闭套接字是多余的。只需关闭输出流。在 bufferOutStream.close();
socket.close();
块中。