【问题标题】:File transfer from C++ client to Java server从 C++ 客户端到 Java 服务器的文件传输
【发布时间】:2010-01-13 14:21:42
【问题描述】:

我有一个需要向 C++ 服务器发送文件的 C++ 客户端。我将文件拆分为 PACKET_SIZE (=1024) 字节块并通过 TCP 套接字发送它们。在服务器端,我最多读取 PACKET_SIZE 个字节到缓冲区。当客户端发送小于 PACKET_SIZE 的文件时,服务器接收的字节数多于发送的字节数。即使我将字节数限制为文件的大小,文件也会有所不同。我知道问题与客户端无关,因为我已经使用 c++ 服务器对其进行了测试,并且它可以完美运行。

谢谢。

服务器:

public void run()  {  
     DataInputStream  input = null;
     PrintWriter output = null;
     try {
         input = new DataInputStream (_client.getInputStream());
     }         
     catch (Exception e) {/* Error handling code */}

     FileHeader fh =  recvHeader(input);      
     size = fh._size;
     filename = fh._name;

     try {
         output = new PrintWriter(_client.getOutputStream(), true);
     }

     catch (Exception e) {/* Error handling code */}

     output.write(HEADER_ACK);
     output.flush();

     FileOutputStream file = null;
     try {
         file = new FileOutputStream(filename);
     }

     catch (FileNotFoundException fnfe) {/* Error handling code */}

     int total_bytes_rcvd = 0, bytes_rcvd = 0, packets_rcvd = 0;
     byte [] buf = new byte [PACKET_DATA_SIZE];

     try {
        int max = (size > PACKET_DATA_SIZE)? PACKET_DATA_SIZE: size;
        bytes_rcvd = input.read(buf,0, max);
        while (total_bytes_rcvd < size) {
                if (-1 == bytes_rcvd) {...}

                ++packets_rcvd;
            total_bytes_rcvd += bytes_rcvd;
            file.write (buf,0, bytes_rcvd);
            if (total_bytes_rcvd < size)        
                   bytes_rcvd = input.read(buf);
            }    

        file.close();

     }

     catch (Exception e) {/* Error handling code */}

}

客户:

char packet [PACKET_SIZE] ;  
file.open (filename, ios::in | ios::binary);//fopen (file_path , "rb");
int max = 0;
if (file.is_open()) {
    if (size > PACKET_SIZE)
        max =  PACKET_SIZE;
    else
        max = size;
    file.read (packet , max);
}

else {...}

int   sent_packets = 0;
while (sent_packets < (int) ceil (((float)size)/PACKET_SIZE) ) { 
        _write=send(_sd , packet, max,0);
        if (_write <0) {...}
        else {
             ++sent_packets;
            if (size > PACKET_SIZE* sent_packets) {
                if (size - PACKET_SIZE* sent_packets >= PACKET_SIZE)
                    max =  PACKET_SIZE;
                else
                    max = size - PACKET_SIZE* sent_packets;
                file.read (packet , max);
            }
        }
}

【问题讨论】:

    标签: java c++ sockets file-upload client-server


    【解决方案1】:

    发送套接字是否在文件末尾关闭,或者下一个文件是否通过同一个套接字流式传输?如果流式传输多个文件,如果recvHeader() 中文件大小的结尾错误,您可以从下一个文件中获取数据,即您发送长度为 0x0102 的文件并尝试读取长度为 0x0201 的文件。

    其他问题,为什么您为第一次读取提供最大值,而不是为同一文件的后续读取提供最大值?

    【讨论】:

      【解决方案2】:

      我看到的一个问题是,您似乎假设如果发送返回非错误,则它发送了您请求发送的整个块。这不一定是真的,尤其是对于流套接字。您发送的数据包有多大,有多少?发生这种情况的最可能原因是,如果套接字的 sndbuf 已满,并且您的套接字 _sd 设置为非阻塞。我不肯定(取决于堆栈实现),但我相信如果您的连接的 TCP 传输窗口已满,并且 tcp 无法将您的整个数据包排入队列,也可能会发生这种情况。

      您可能应该循环发送直到发送最大值。

      因此:

      int send_ct=0;
      while( (_write = send(_sd, packet + send_ct, max-send_ct, 0)) > 0) {
         send_ct += _write;
         if(send_ct >= max) {
            break;
         } else {
            // Had to do another send
         }
      }
      

      【讨论】:

        【解决方案3】:

        代码不完整。例如。您省略了文件名和文件大小的发送,以及这些值的解析。这些值是否正确?如果不是,请先确保这些值是正确的,然后再进一步调查。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-12-27
          • 2010-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多