web-dev-qa-db-ja.com

Javaソケットを介したファイル(byte [])の送受信

クライアントがファイルをバイトに変換し、それをサーバーに送信してから、バイトをファイルに戻す非常に単純なクライアント/サーバーを開発しようとしています。

現在、プログラムは空のファイルを作成するだけです。私は素晴らしいJava開発者ではないので、どんな助けでも大歓迎です。

これは、クライアントが送信するものを受信するサーバー部分です。

ServerSocket serverSocket = null;

    serverSocket = new ServerSocket(4444);


    Socket socket = null;
    socket = serverSocket.accept();

    DataOutputStream out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    DataInputStream in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));
    byte[] bytes = new byte[1024];

    in.read(bytes);
    System.out.println(bytes);

    FileOutputStream fos = new FileOutputStream("C:\\test2.xml");
    fos.write(bytes);

そして、これがクライアント部分です

Socket socket = null;
    DataOutputStream out = null;
    DataInputStream in = null;
    String Host = "127.0.0.1";     

    socket = new Socket(Host, 4444);
    out = new DataOutputStream(new BufferedOutputStream(socket.getOutputStream()));
    in = new DataInputStream(new BufferedInputStream(socket.getInputStream()));

    File file = new File("C:\\test.xml");
    //InputStream is = new FileInputStream(file);
    // Get the size of the file
    long length = file.length();
    if (length > Integer.MAX_VALUE) {
        System.out.println("File is too large.");
    }
    byte[] bytes = new byte[(int) length];

    //out.write(bytes);
    System.out.println(bytes);

    out.close();
    in.close();
    socket.close();
58
Rookie

Javaのストリームをコピーする正しい方法は次のとおりです。

int count;
byte[] buffer = new byte[8192]; // or 4096, or more
while ((count = in.read(buffer)) > 0)
{
  out.write(buffer, 0, count);
}

フォーラムに投稿するたびに1ドルがあればいいのに。

66
user207421

助けてくれたおかげで、私はそれをうまく機能させることができたので、他の人が彼らを助けることができるように投稿したいと思いました。

サーバ

public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocket serverSocket = null;

        try {
            serverSocket = new ServerSocket(4444);
        } catch (IOException ex) {
            System.out.println("Can't setup server on this port number. ");
        }

        Socket socket = null;
        InputStream in = null;
        OutputStream out = null;

        try {
            socket = serverSocket.accept();
        } catch (IOException ex) {
            System.out.println("Can't accept client connection. ");
        }

        try {
            in = socket.getInputStream();
        } catch (IOException ex) {
            System.out.println("Can't get socket input stream. ");
        }

        try {
            out = new FileOutputStream("M:\\test2.xml");
        } catch (FileNotFoundException ex) {
            System.out.println("File not found. ");
        }

        byte[] bytes = new byte[16*1024];

        int count;
        while ((count = in.read(bytes)) > 0) {
            out.write(bytes, 0, count);
        }

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

とクライアント

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = null;
        String Host = "127.0.0.1";

        socket = new Socket(Host, 4444);

        File file = new File("M:\\test.xml");
        // Get the size of the file
        long length = file.length();
        byte[] bytes = new byte[16 * 1024];
        InputStream in = new FileInputStream(file);
        OutputStream out = socket.getOutputStream();

        int count;
        while ((count = in.read(bytes)) > 0) {
            out.write(bytes, 0, count);
        }

        out.close();
        in.close();
        socket.close();
    }
}
63
Rookie

これがサーバーです。ファイルへのストリームを開き、ネットワーク経由で送信します

import Java.io.BufferedInputStream;
import Java.io.File;
import Java.io.FileInputStream;
import Java.io.IOException;
import Java.io.OutputStream;
import Java.net.ServerSocket;
import Java.net.Socket;

public class SimpleFileServer {

  public final static int SOCKET_PORT = 5501;
  public final static String FILE_TO_SEND = "file.txt";

  public static void main (String [] args ) throws IOException {
    FileInputStream fis = null;
    BufferedInputStream bis = null;
    OutputStream os = null;
    ServerSocket servsock = null;
    Socket sock = null;
    try {
      servsock = new ServerSocket(SOCKET_PORT);
      while (true) {
        System.out.println("Waiting...");
        try {
          sock = servsock.accept();
          System.out.println("Accepted connection : " + sock);
          // send file
          File myFile = new File (FILE_TO_SEND);
          byte [] mybytearray  = new byte [(int)myFile.length()];
          fis = new FileInputStream(myFile);
          bis = new BufferedInputStream(fis);
          bis.read(mybytearray,0,mybytearray.length);
          os = sock.getOutputStream();
          System.out.println("Sending " + FILE_TO_SEND + "(" + mybytearray.length + " bytes)");
          os.write(mybytearray,0,mybytearray.length);
          os.flush();
          System.out.println("Done.");
        } catch (IOException ex) {
          System.out.println(ex.getMessage()+": An Inbound Connection Was Not Resolved");
        }
        }finally {
          if (bis != null) bis.close();
          if (os != null) os.close();
          if (sock!=null) sock.close();
        }
      }
    }
    finally {
      if (servsock != null)
        servsock.close();
    }
  }
}

これがクライアントですネットワーク経由で送信されているファイルを受信します

import Java.io.BufferedOutputStream;
import Java.io.FileOutputStream;
import Java.io.IOException;
import Java.io.InputStream;
import Java.net.Socket;

public class SimpleFileClient {

  public final static int SOCKET_PORT = 5501;
  public final static String SERVER = "127.0.0.1";
  public final static String
       FILE_TO_RECEIVED = "file-rec.txt";

  public final static int FILE_SIZE = Integer.MAX_VALUE;

  public static void main (String [] args ) throws IOException {
    int bytesRead;
    int current = 0;
    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    Socket sock = null;
    try {
      sock = new Socket(SERVER, SOCKET_PORT);
      System.out.println("Connecting...");

      // receive file
      byte [] mybytearray  = new byte [FILE_SIZE];
      InputStream is = sock.getInputStream();
      fos = new FileOutputStream(FILE_TO_RECEIVED);
      bos = new BufferedOutputStream(fos);
      bytesRead = is.read(mybytearray,0,mybytearray.length);
      current = bytesRead;

      do {
         bytesRead =
            is.read(mybytearray, current, (mybytearray.length-current));
         if(bytesRead >= 0) current += bytesRead;
      } while(bytesRead > -1);

      bos.write(mybytearray, 0 , current);
      bos.flush();
      System.out.println("File " + FILE_TO_RECEIVED
          + " downloaded (" + current + " bytes read)");
    }
    finally {
      if (fos != null) fos.close();
      if (bos != null) bos.close();
      if (sock != null) sock.close();
    }
  }    
}
3
Jay Godara

ファイルサイズの制限を回避するために、ファイルサイズbyte[] bytes = new byte[(int) length];の配列を作成するときに例外Java.lang.OutOfMemoryErrorがスローされる可能性がありますが、代わりに

    byte[] bytearray = new byte[1024*16];
    FileInputStream fis = null;
    try {

        fis = new FileInputStream(file);
        OutputStream output= socket.getOututStream();
        BufferedInputStream bis = new BufferedInputStream(fis);

        int readLength = -1;
        while ((readLength = bis.read(bytearray)) > 0) {
            output.write(bytearray, 0, readLength);

        }
        bis.close();
        output.close();
    }
    catch(Exception ex ){

        ex.printStackTrace();
    } //Excuse the poor exception handling...
1
QuakeCore

ルーキー、ソケットでファイルをサーバーに書き込みたい場合、dataoutputstreamの代わりにfileoutputstreamを使用してはどうですか? dataoutputstreamは、プロトコルレベルの読み取り/書き込みにより適しています。読み取りおよび書き込みのバイト単位のコードではあまり合理的ではありません。 Java ioでは、読み取りと書き込みのループが必要です。また、バッファ方式を使用します。フラッシュが必要です。コードサンプルは次のとおりです。 http://www.rgagnon.com/javadetails/Java-0542.html

0
horaceman