通过网络发送时,Java文件无法正常工作

时间:2015-04-25 13:38:38

标签: java tcp client mp3 server

所以我正在为java实现客户端和套接字。我想通过套接字在tcp上发送大文件,我也能发送文件,但唯一的问题是另一端的文件要么不完整要么不能正常工作。我检查了位被转移然后是什么错误。

客户端:



   Socket sock = new Socket("127.0.0.1", 1056);
    byte[] mybytearray = new byte[1024];
    InputStream is = sock.getInputStream();
    FileOutputStream fos = new FileOutputStream("abc.mp3");
    BufferedOutputStream bos = new BufferedOutputStream(fos);
    int bytesRead = is.read(mybytearray, 0, mybytearray.length);
    int len = 0;
    while((len = is.read(mybytearray)) != -1)
    {
    bos.write(mybytearray, 0, len);
    System.out.println("sending");
    }
  
    bos.close();
    sock.close();




服务器端:



  ServerSocket ss = new ServerSocket(1056);
    while (true) {
      Socket s = ss.accept();
      PrintStream out = new PrintStream(s.getOutputStream());
      BufferedReader in = new BufferedReader(new InputStreamReader(s.getInputStream()));
      String info = null;
      String request = null;
      System.out.println("sending");      
    	  String filename = "abc.mp3";
        File fi = new File(filename);
        InputStream fs = new FileInputStream(fi);
        int n = fs.available();
        byte buf[] = new byte[1024];
        out.println("Content_Length:" + n);
        out.println("");
        while ((n = fs.read(buf)) >= 0) {
          out.write(buf, 0, n);
             System.out.println("sending");
        }
        out.close();
        s.close();
        in.close();
		
		}




2 个答案:

答案 0 :(得分:1)

当您通过TCP连接时,您可以创建一个可以读写的网络流,类似于您使用的所有其他流。将大量数据写入流不是一个好主意,因此我建议您将所选文件分成较小的数据包,其中每个数据包长度为1024字节(1KB),然后将所有数据包发送到服务器。 SendTCP函数如下:(我使用Windows窗体使事情变得更加明显)

public void SendTCP(string M, string IPA, Int32 PortN)
{
    byte[] SendingBuffer = null
    TcpClient client = null;
    lblStatus.Text = "";
    NetworkStream netstream = null;
    try
    {
         client = new TcpClient(IPA, PortN);
         lblStatus.Text = "Connected to the Server...\n";
         netstream = client.GetStream();
         FileStream Fs = new FileStream(M, FileMode.Open, FileAccess.Read);
         int NoOfPackets = Convert.ToInt32
      (Math.Ceiling(Convert.ToDouble(Fs.Length) / Convert.ToDouble(BufferSize)));
         progressBar1.Maximum = NoOfPackets;
         int TotalLength = (int)Fs.Length, CurrentPacketLength, counter = 0;
         for (int i = 0; i < NoOfPackets; i++)
         {
             if (TotalLength > BufferSize)
             {
                 CurrentPacketLength = BufferSize;
                 TotalLength = TotalLength - CurrentPacketLength;
             }
             else
                 CurrentPacketLength = TotalLength;
                 SendingBuffer = new byte[CurrentPacketLength];
                 Fs.Read(SendingBuffer, 0, CurrentPacketLength);
                 netstream.Write(SendingBuffer, 0, (int)SendingBuffer.Length);
                 if (progressBar1.Value >= progressBar1.Maximum)
                      progressBar1.Value = progressBar1.Minimum;
                 progressBar1.PerformStep();
             }

             lblStatus.Text=lblStatus.Text+"Sent "+Fs.Length.ToString()+" 
                        bytes to the server";
             Fs.Close();
         }
    catch (Exception ex)
    {
         Console.WriteLine(ex.Message);
    }
    finally
    {
         netstream.Close();
         client.Close();
    }
} 

如您所见,正在构建TCP客户端和网络流,并启动网络连接。根据1024字节的缓冲区大小打开所选文件后,将计算要发送的数据包的数量。还有另外两个变量CurrentPacketLength和TotalLength。如果所选文件的总长度大于缓冲区大小,则将CurrentPacketLength设置为缓冲区大小,否则为什么要发送一些空字节,因此将CurrentPacketLength设置为文件的总长度。之后,我从总长度中减去电流,实际上我们可以说总长度显示的是尚未发送的数据总量。其余的非常简单,从文件流中读取数据并根据CurrentPacketLength将其写入SendingBuffer并将缓冲区写入网络流。

服务器端,应用程序正在侦听传入连接:

public void ReceiveTCP(int portN)
{
    TcpListener Listener = null;
    try
    {
        Listener = new TcpListener(IPAddress.Any, portN);
        Listener.Start();
    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.Message);
    }

    byte[] RecData = new byte[BufferSize];
    int RecBytes;

    for (; ; )
    {
        TcpClient client = null;
        NetworkStream netstream = null;
        Status = string.Empty;
        try
        {                          
             string message = "Accept the Incoming File ";
             string caption = "Incoming Connection";
             MessageBoxButtons buttons = MessageBoxButtons.YesNo;
             DialogResult result;

             if (Listener.Pending())
             {
                  client = Listener.AcceptTcpClient();
                  netstream = client.GetStream();
                  Status = "Connected to a client\n";
                  result = MessageBox.Show(message, caption, buttons);

                  if (result == System.Windows.Forms.DialogResult.Yes)
                  {
                       string SaveFileName=string.Empty;
                       SaveFileDialog DialogSave = new SaveFileDialog();
                       DialogSave.Filter = "All files (*.*)|*.*";
                       DialogSave.RestoreDirectory = true;
                       DialogSave.Title = "Where do you want to save the file?";
                       DialogSave.InitialDirectory = @"C:/";
                       if (DialogSave.ShowDialog() == DialogResult.OK)
                            SaveFileName = DialogSave.FileName;
                       if (SaveFileName != string.Empty)
                       {
                           int totalrecbytes = 0;
                           FileStream Fs = new FileStream
            (SaveFileName, FileMode.OpenOrCreate, FileAccess.Write);
                           while ((RecBytes = netstream.Read
                (RecData, 0, RecData.Length)) > 0)
                           {
                                Fs.Write(RecData, 0, RecBytes);
                                totalrecbytes += RecBytes;
                           }
                           Fs.Close();
                       }
                       netstream.Close();
                       client.Close();
                  }
             }
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            //netstream.Close();
        }
    }
}

创建TCP侦听器并开始侦听指定的端口。缓冲区大小再次设置为1024字节。在调用AcceptTcpClient方法之前,TCP侦听器可以预先检查是否有任何挂起的连接。如果有任何挂起的连接,则返回true。此方法是避免套接字被阻止的好方法。在从网络流中读取任何内容之前,会出现一个消息框询问您是否要接受传入连接,然后将打开SaveFileDialog,当您输入文件名加扩展名时,将构建一个文件流并开始从网络流和写入文件流。在代码中创建一个线程,并在创建的线程中运行接收方法。我已经在应用程序的LAN中发送了超过100 MB的文件。

有关详细信息,请查看此article

答案 1 :(得分:1)

所以,首先你要这样做

int bytesRead = is.read(mybytearray, 0, mybytearray.length);

将最多1024个字节读入mybytearray。

你不做任何事情,我不明白你为什么这样做。你永远不会写那些字节,所以如果while循环读取任何东西它们会被覆盖。 只需删除它。 while循环应涵盖所有这些。