我正在開發一個程序,用戶可以下載一些文件。現在,我首先將文件列表發送給用戶。所以從列表中,用戶一次選擇一個文件並提供存儲該文件的路徑。反過來,它也爲服務器提供文件的路徑。線程在套接字程序中面臨死鎖
我正在採用這種方法,因爲我想給像沒有文件大小限制的體驗。
這裏是我的代碼..
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給用戶並且用戶已經成功接收文件a並且現在他正在請求文件b),則在這種情況下程序面臨死鎖。它正在等待套接字的輸入流。我把斷點,並試圖調試它,但它不會在FileThread的第二次運行方法。我在這裏找不到這個錯誤。基本上我正在製作局域網上的LAN Messenger。我正在使用SWT作爲UI框架。
[socket.close()](http://docs.oracle.com/javase/6/docs/api/java/net/Socket.html#close()「API javadoc」)滑 – gnat 2012-04-13 13:15:38
@gnat:我不明白你在說什麼......你能詳細說明一下嗎? – ankurtr 2012-04-13 13:26:14
BTW:在創建ObjectInputStream之前,您應該創建並刷新ObjectOutputStream,否則會導致死鎖。 – 2012-04-13 13:40:28