Я разрабатываю одну программу, в которой пользователь может загрузить несколько файлов. Теперь сначала я отправляю список файлов пользователю. Поэтому из списка пользователь выбирает один файл за раз и предоставляет путь для хранения этого файла. В свою очередь, он также дает серверу путь к файлу, где он существует.Нити сталкиваются с тупиком в программе сокетов
Я следую этому подходу, потому что хочу дать поток, как опыт без ограничения размера файла.
Вот мой код ..
1) Это сервер, который запускается каждый раз, когда я начинаю мое приложение
public class FileServer extends Thread {
private ServerSocket socket = null;
public FileServer() {
try {
socket = new ServerSocket(Utils.tcp_port);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void run() {
try {
System.out.println("request received");
new FileThread(socket.accept()).start();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
2) Эта нить работает для каждого клиента отдельно и посылает требуемый файл в данные пользователя 8kb за раз.
public class FileThread extends Thread {
private Socket socket;
private String filePath;
public String getFilePath() {
return filePath;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public FileThread(Socket socket) {
this.socket = socket;
System.out.println("server thread" + this.socket.isConnected());
//this.filePath = filePath;
}
@Override
public void run() {
// TODO Auto-generated method stub
try
{
ObjectInputStream ois=new ObjectInputStream(socket.getInputStream());
try {
//************NOTE
filePath=(String) ois.readObject();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
File f = new File(this.filePath);
byte[] buf = new byte[8192];
InputStream is = new FileInputStream(f);
BufferedInputStream bis = new BufferedInputStream(is);
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
int c = 0;
while ((c = bis.read(buf, 0, buf.length)) > 0) {
oos.write(buf, 0, c);
oos.flush();
// buf=new byte[8192];
}
oos.close();
//socket.shutdownOutput();
// client.shutdownOutput();
System.out.println("stop");
// client.shutdownOutput();
ois.close();
// Thread.sleep(500);
is.close();
bis.close();
socket.close();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
ПРИМЕЧАНИЕ: здесь filePath представляет путь к файлу, где он существует на сервере. Клиент, который подключается к серверу, предоставляет этот путь. Я управляю этим через сокеты, и я успешно получаю этот путь.
3) FileReceiverThread несет ответственность за получение данных с сервера и создание файла из этих данных буфера.
public class FileReceiveThread extends Thread {
private String fileStorePath;
private String sourceFile;
private Socket socket = null;
public FileReceiveThread(String ip, int port, String fileStorePath,
String sourceFile) {
this.fileStorePath = fileStorePath;
this.sourceFile = sourceFile;
try {
socket = new Socket(ip, port);
System.out.println("receive file thread " + socket.isConnected());
} catch (IOException ex) {
ex.printStackTrace();
}
}
@Override
public void run() {
try {
ObjectOutputStream oos = new ObjectOutputStream(
socket.getOutputStream());
oos.writeObject(sourceFile);
oos.flush();
// oos.close();
File f = new File(fileStorePath);
OutputStream os = new FileOutputStream(f);
BufferedOutputStream bos = new BufferedOutputStream(os);
byte[] buf = new byte[8192];
int c = 0;
//************ NOTE
ObjectInputStream ois = new ObjectInputStream(
socket.getInputStream());
while ((c = ois.read(buf, 0, buf.length)) > 0) {
// ois.read(buf);
bos.write(buf, 0, c);
bos.flush();
// buf = new byte[8192];
}
ois.close();
oos.close();
//
os.close();
bos.close();
socket.close();
//Thread.sleep(500);
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
ПРИМЕЧАНИЕ: В настоящее время проблема, что я столкнулся это в первый раз, когда файл запрашивается результатом программы является такой же, как все мои ожидания. Я могу передать любой размер файла в первый раз. Теперь, когда запрашивается второй файл (например, я отправил файл a, b, c, d пользователю, и пользователь успешно получил файл, и теперь он запрашивает файл b) в этой ситуации программа сталкивается с тупиковой ситуацией. Он ожидает входной поток сокета. Я поставил точку останова и попытался ее отладить, но второй раз не запускается метод FileThread. Я не мог узнать здесь ошибку. В основном я создаю LAN Messenger, который работает в локальной сети. Я использую SWT в качестве интерфейса пользовательского интерфейса.
[socket.close()] (http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html#close() «API javadoc») в FileReceiveThread.run чувствует slippery – gnat
@gnat: Я не понимаю, что вы говорите ... Не могли бы вы подробнее рассказать? – ankurtr
BTW: вы должны создать и очистить ObjectOutputStream до создания объекта ObjectInputStream, или это может привести к блокировке. –