Java通过套接字发送和接收文件(字节[])

Java通过套接字发送和接收文件(字节[]),java,file,sockets,client,Java,File,Sockets,Client,我试图开发一个非常简单的客户机/服务器,客户机将文件转换为字节,发送到服务器,然后将字节转换回文件 目前程序只创建一个空文件。我不是一个出色的Java开发人员,因此非常感谢任何帮助 这是接收客户端发送的内容的服务器部分 ServerSocket serverSocket = null; serverSocket = new ServerSocket(4444); Socket socket = null; socket = serverSocket.accept()

我试图开发一个非常简单的客户机/服务器,客户机将文件转换为字节,发送到服务器,然后将字节转换回文件

目前程序只创建一个空文件。我不是一个出色的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();

在Java中复制流的正确方法如下:

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

希望我每次在论坛上发布都能得到一美元。

新手,如果你想通过套接字将文件写入服务器,用fileoutputstream代替dataoutputstream怎么样?dataoutputstream更适合协议级读写。您的代码在字节读写方面不是很合理。读写循环在JavaIO中是必需的。而且,您使用缓冲区方式。冲洗是必要的。下面是一个代码示例:

谢谢您的帮助。我已经设法让它现在工作,所以我想我会张贴,以便其他人可以用来帮助他们

服务器:

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();
    }
}
这是服务器 打开文件流并通过网络发送

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();
    }
  }    
}
这是客户 接收通过网络发送的文件

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();
    }
  }    
}

为了避免文件大小的限制,当创建文件大小的数组时,可能会导致引发异常
java.lang.OutOfMemoryError
,该异常
byte[]bytes=新字节[(int)长度],我们可以这样做

    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...

总结EJP的答案;使用此选项可提高流动性。 确保不要将他的代码放入一个更大的try-catch中。read和catch块之间有更多的代码,它可能会返回一个异常并一直跳转到外部catch块,最安全的方法是将EJPS的while循环放入try-catch中,然后在其后继续代码,如:

int count;
byte[] bytes = new byte[4096];
try {
    while ((count = is.read(bytes)) > 0) {
        System.out.println(count);
        bos.write(bytes, 0, count);
    }
} catch ( Exception e )
{
    //It will land here....
}
// Then continue from here
编辑:^这发生在我身上,因为我没有意识到如果是客户端到服务器的流,您需要放置socket.shutDownOutput()



希望这篇文章能解决你的任何问题

我打赌你扔掉了所有的例外。。。请发布整个程序。您的客户端不会向其输出流写入任何内容,并且您的服务器会忽略读取方法的结果。谷歌的“Java IO教程”。是解决方案的答案可以修改为聊天和文件共享在同一时间和同一套接字流谢谢!我已经研究了read方法,在这里你已经写了count,这就是文件的长度,对吗?另外,当收到字节时,您将如何反转该代码?不,
count
是一个
int
变量,其中存储每个
read()
方法调用的结果,如代码所述。接收时的代码是相同的,只是不同的输入和输出。另一种正确的方法是:Guava的
ByTestStreams.copy(InputStream from,OutputStream to)
@yshavit有几十个包装器,但它们都执行此代码,如果他们不知道,他们应该这样做。当接收到的文件大小以前未知时,我如何在服务器上设置缓冲区大小?啊,这很有用,谢谢!问题-接收代码,静态接收的文件大小。您将如何进行动态设置?是否有一种方法可以在字节数组之前发送文件长度?您不能使用FileOutputStream到套接字,以这种方式使用DataOutputStream没有什么错。这个答案没有意义。在
close(),
之前,
flush()
是不必要的,并且您提供的链接中的代码不会执行您在此处推荐的任何操作。它也不起作用。@LucasAmos它是垃圾。例如,作者没有解释客户机如何神奇地提前知道fie大小,或者为什么整个文件应该在两端加载到内存中。它将在空文件上异常失败。文件复制远比这简单。没有理由通过分配整个文件大小的缓冲区来浪费空间:这不能扩展到大文件,也不能用于2GB以上的文件。8192的缓冲区对于大多数用途来说是足够的。它与套接字接收缓冲区大小也没有任何关系。您不需要任何flush()调用,只需关闭“out”和“bis”。这里有太多不必要和浪费的代码。
if(length>Integer.MAX\u VALUE)
应该是
if(length>Long.MAX\u VALUE)
,因为
length
Long
不是
int
@AltianoGerung执行此检查的原因是数组不能更大。但如果阵列的固定大小(16k)小得多,则不需要进行检查。我删除了这一部分,作为一个公认的答案,它不应该有那么大的错误。@AltianoGerung A
long
不能大于
long.MAX\u值
。你的建议没有意义。我使用字节方法将图像文件从客户端发送到服务器。是否有其他人在while循环中被卡住了。我让它发送文件,我可以在服务器运行时打开它,但文件说它的大小是0字节。有什么想法吗?新字节[100*1024];这是100KB而不是100MB。即使这样也太多了。您不需要比套接字发送缓冲区更多的缓冲,通常不超过64k。@EJP我确实意识到100MB缓冲区只不过是内存浪费,多亏了您。请参阅我的评论。您不需要
shutdownOutput()
。关闭插座具有相同的效果。如果复制时出现
IOException
,您确实希望立即停止。几乎可以肯定的是,除了关上插座,你再也做不了什么了。