2011-06-30 14 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

出力ストリームをサーバー側からフラッシュしないでください。メッセージが表示されます: 'クライアントに送信されたメッセージはOKですか? ' – Lynch

+0

uresponsiveの部分にコメントする予定です。クライアントが応答(読み込み応答)を待っている場合、私はそれが応答しないと思います。リクエストを別のスレッドで行うことを検討しましたか?クライアント側の – Andreas

+0

では、 "Bytes Sent:.."の後にブロックされます。 最初の部分にコメントすると機能しています。 2番目の部分にコメントすると機能しています。 両方が動作していません。 – 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を決して見ることができません。

送信されたバイトを数える方法を修正してください。実際には、1024の代わりに0から始まり、実際に読み取ったバイト数だけそのカウンタをインクリメントする必要があります。

+0

ありがとうございます。 私はそれがソケットのようなものだったと思っていました。私は、フラッシュ、reseet、閉鎖などを試みた – ophelie88

+0

すべての確認コードは冗長であり、不要です。 –

+0

現在の形では本当に冗長です。しかし、サーバーがいくつかの情報(データが格納されているファイル名、ディスクがいっぱいだった場合のエラーコード)を返すとすぐに、このプロトコルは非常に便利になります。例えば、サーバが 'ok'を先に送信せずにソケットを閉じただけであれば、クライアントは最後のバイトが正常に書き込まれたことをどのように知るでしょうか? –

0

HTTPを使用してください!これはまさにこのタイプの問題のために設計されています。 Javaには自由に利用できるHTTPクライアントとサーバーライブラリがたくさんあります。

+2

これはコメントではありませんか? – pqsk