2011-06-30 208 views
4

我試圖從客戶端向服務器發送文件。服務器接收文件,然後向客戶端發送確認消息。發送文件,然後通過套接字發送消息

我的問題是客戶端在等待確認時變得無響應。

服務器:

import java.net.*; 
import java.io.*; 

public class Server { 
public static void main(String args[]) throws IOException { 
     int port = 1234; 
    ServerSocket server_socket; 

    server_socket = new ServerSocket(port); 
    System.out.println("Server waiting for client on port " 
      + server_socket.getLocalPort()); 
    // server infinite loop 
    while (true) { 
     Socket socket = server_socket.accept(); 
     System.out.println("New connection accepted " 
       + socket.getInetAddress() + ":" + socket.getPort()); 
    try { 
       byte[] b = new byte[1024]; 
       int len = 0; 
       int bytcount = 1024; 
       String FileName = "C:\\test\\java\\tmp\\sentfile.pdf"; 
       FileOutputStream inFile = new FileOutputStream(FileName); 
       InputStream is = socket.getInputStream(); 
       BufferedInputStream in2 = new BufferedInputStream(is, 1024); 
       while ((len = in2.read(b, 0, 1024)) != -1) { 
        bytcount = bytcount + 1024; 
       inFile.write(b, 0, len); 
       } 
       System.out.println("Bytes Writen : " + bytcount); 

       //Sending the response back to the client. 
       ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
       oos.flush(); 
       oos.writeObject("ok"); 
       System.out.println("Message sent to the client is "+"ok"); 

       in2.close(); 
       inFile.close(); 
      } catch (IOException e) { 
     System.out.println("Unable to open file" + e); 
     return; 
    } 
    socket.close(); 
    System.out.println("Connection closed by client"); 
     } 
} 
} 

客戶:

import java.net.*; 
import java.io.*; 

public class Client { 
    public static void main(String[] args) throws UnknownHostException, 
     IOException, ClassNotFoundException { 

     int port = 1234; 
    Socket socket = null; 

    // connect to server 
    socket = new Socket("127.0.0.1", port); 

    try { 
      byte[] buf = new byte[1024]; 
      OutputStream os = socket.getOutputStream(); 
      BufferedOutputStream out = new BufferedOutputStream(os, 1024); 
      String file = "C:\\test\\java\\client\\source.pdf"; 
      FileInputStream in = new FileInputStream(file); 
      int i = 0; 
      int bytecount = 1024; 
      while ((i = in.read(buf, 0, 1024)) != -1) { 
       bytecount = bytecount + 1024; 
      out.write(buf, 0, i); 
      out.flush(); 
      } 
      System.out.println("Bytes Sent :" + bytecount); 

      ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
      String confirmation = (String) ois.readObject(); 
      System.out.println("from server : " + confirmation); 

      out.close(); 
      in.close(); 
    } catch (IOException e) { 
    System.out.println(e); 
    } 
    socket.close(); 
} 
} 
+0

可能你不會從服務器端刷新輸出流嗎?你看到這條消息:'發送給客戶端的消息是否可以'? – Lynch

+0

將對無響應部分發表評論。如果客戶端正在等待響應(閱讀響應),那麼我想它會沒有響應。您是否考慮過在單獨的線程中提出請求?在客戶端的 – Andreas

+0

,它在「Bytes Sent:..」之後被阻塞。 如果我評論第一部分,它是工作。 如果我對第二部分發表評論,它正在工作。 兩者都不行。 – ophelie88

回答

7

下面是完整的工作示例。服務器:

package so6540787; 

import java.io.BufferedInputStream; 
import java.io.File; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.ObjectOutputStream; 
import java.net.ServerSocket; 
import java.net.Socket; 

public class Server { 

    private final Socket socket; 

    public Server(Socket socket) { 
    this.socket = socket; 
    } 

    public void receiveFile(File file) throws IOException { 
    byte[] b = new byte[1024]; 
    int len = 0; 
    int bytcount = 1024; 
    FileOutputStream inFile = new FileOutputStream(file); 
    InputStream is = socket.getInputStream(); 
    BufferedInputStream in2 = new BufferedInputStream(is, 1024); 
    while ((len = in2.read(b, 0, 1024)) != -1) { 
     bytcount = bytcount + 1024; 
     inFile.write(b, 0, len); 
    } 
    System.out.println("Bytes Writen : " + bytcount); 

    // Sending the response back to the client. 
    ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream()); 
    oos.flush(); 
    oos.writeObject("ok"); 
    System.out.println("Message sent to the client is " + "ok"); 

    in2.close(); 
    inFile.close(); 
    } 

    public static void main(String[] args) throws IOException { 
    ServerSocket listen = new ServerSocket(10000, 1); 
    Socket socket = listen.accept(); 
    Server server = new Server(socket); 
    server.receiveFile(new File("c:/received.pdf")); 
    } 
} 

而且客戶端:

package so6540787; 

import java.io.BufferedOutputStream; 
import java.io.File; 
import java.io.FileInputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.OutputStream; 
import java.net.Socket; 

public class Client { 

    private final Socket socket; 

    public Client(Socket socket) { 
    this.socket = socket; 
    } 

    public void sendFile(File file) throws IOException, ClassNotFoundException { 
    byte[] buf = new byte[1024]; 
    OutputStream os = socket.getOutputStream(); 
    BufferedOutputStream out = new BufferedOutputStream(os, 1024); 
    FileInputStream in = new FileInputStream(file); 
    int i = 0; 
    int bytecount = 1024; 
    while ((i = in.read(buf, 0, 1024)) != -1) { 
     bytecount = bytecount + 1024; 
     out.write(buf, 0, i); 
     out.flush(); 
    } 
    socket.shutdownOutput(); /* important */ 
    System.out.println("Bytes Sent :" + bytecount); 

    ObjectInputStream ois = new ObjectInputStream(socket.getInputStream()); 
    ois.skip(Long.MAX_VALUE); 
    String confirmation = (String) ois.readObject(); 
    System.out.println("from server : " + confirmation); 

    out.close(); 
    in.close(); 
    } 

    public static void main(String[] args) throws IOException, ClassNotFoundException { 
    Client client = new Client(new Socket("localhost", 10000)); 
    client.sendFile(new File("c:/tobesent.pdf")); 
    } 
} 

你缺少的行是 「socket.shutdownOutput()」。如果將該行保留,服務器將永遠不會從read調用中看到文件結束標記-1

請修復您計算已發送字節的方式。您應該真正從0開始而不是1024開始,並且只能通過實際讀取的字節數增加該計數器。

+0

謝謝。 我認爲這是類似的東西,清除插座。我嘗試沖洗,重新放置,關閉等。 – ophelie88

+0

所有的確認代碼都是多餘的和不必要的。 –

+0

在目前的形式,它真的是多餘的。但是,只要服務器發回一些信息(數據已存儲的文件名,如果磁盤已滿,則爲錯誤代碼),該協議就變得非常有用。例如,如果服務器剛剛關閉套接字而不先發送「ok」,客戶端如何知道最後一個字節已成功寫入? –

0

使用HTTP!它專爲這種類型的問題而設計。有大量HTTP客戶端和服務器庫可供Java免費使用。

+2

不應該這是一個評論? – pqsk