通过Socket将文件从PC发送到Android

时间:2013-12-05 11:17:59

标签: android delphi sockets

我在Android上从计算机上发送文件有两个问题 第一个问题,使用以下代码发送

Socket sock;
try {
    sock = new Socket("172.16.3.120", 1025); 
    System.out.println("Connecting...");

    // sendfile
    File myFile = new File (Environment.getExternalStorageDirectory().getPath() + "/UchTeh/uchteh.db"); 
    byte [] mybytearray  = new byte [(int)myFile.length()];
    FileInputStream fis = new FileInputStream(myFile);
    BufferedInputStream bis = new BufferedInputStream(fis);
    bis.read(mybytearray,0,mybytearray.length);
    OutputStream os = sock.getOutputStream();
    System.out.println("Sending...");
    os.write(mybytearray,0,mybytearray.length);
    os.flush();

    sock.close();
} catch (UnknownHostException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
计算机上的

文件接受delphi

procedure TServerRcvThread.ClientExecute;
var
  SockStream : TWinSocketStream;
  FileInfo   : TFileInfo;
  FileStream : TFileStream;
  RcvBuf     : array[0..140] of Byte;
  nRead      : Integer;
  nToRead    : Integer;
  nTotal     : Integer;
begin
  FStatus := 'Unknown error';
  SockStream := TWinSocketStream.Create( ClientSocket, 10000 );
  try
    if SockStream.WaitForData(10000) then begin
      nRead := SockStream.Read( FileInfo, SizeOf(FileInfo) );
      if (nRead = SizeOf(FileInfo)) then  begin
        nTotal := 0;
        FileStream := TFileStream.Create( FDir + '\' + FileInfo.FileName, fmCreate );
        try
          while(nTotal < FileInfo.FileLength) do begin
            nToRead := (FileInfo.FileLength - nTotal);
            if (nToRead > SizeOf(RcvBuf)) then
              nToRead := SizeOf(RcvBuf);
            nRead := SockStream.Read( RcvBuf, nToRead );
            if (nRead = 0) then Exit;
            nTotal := nTotal + nRead;
            FileStream.Write( RcvBuf, nRead );
          end;
        finally
          FileStream.Free;
        end;
        if (nTotal = FileInfo.FileLength) then
          FStatus := 'File ' + FileInfo.FileName + ' received ('
                   + IntToStr(nTotal) + ' bytes)'
        else
          FStatus := 'File ' + FileInfo.FileName + ' error ('
                  + IntToStr(nTotal) + ' bytes)';
      end
      else
        FStatus := 'File info header error';
    end
    else begin
      FStatus := 'Client delay error';
      ClientSocket.Close;
      Terminate;
    end;
  finally
    SockStream.Free;
    Synchronize( SetStatus );
  end;
end;

文件大小发送和接收各种 请帮助我,我自己也不会理解它的问题

1 个答案:

答案 0 :(得分:0)

您的Android代码本身只发送原始文件内容而没有其他内容,但Delphi代码期望首先接收TFileInfo记录,然后是文件数据。因此,在源文件本身在其原始数据的开头包含准确的TFileInfo之前,您的Delphi代码才会起作用。是吗?

如果它是一个多字节整数(你没有显示TFileInfo.FileLength被定义为什么),那么在阅读TFileInfo时你也没有考虑到endian。您必须确保多字节整数值与Delphi期望的端口相同。我不知道Android用于多字节整数值的endian。在传输多字节整数时,大多数网络协议都在网络字节顺序上标准化,因此您应该在协议中采用相同的约定。

如果文件确实包含TFileInfo记录,则首先从文件中读取它,根据需要交换其整数字段的endian,传输它,然后完成传输剩余的文件数据。否则,您需要创建并发送适当的TFileInfo,然后再发送完整的文件数据。

在Delphi端,您可以读取TFileInfo(无论它来自何处),根据需要交换其整数字段的endian,然后读完剩余的文件数据。

如果在所有这些之后,您仍然遇到问题,那么您需要更新您的问题,更详细地说明您的代码究竟出现了什么问题(错误消息,意外症状等),实际上是什么数据在源文件等