简体   繁体   English

从C ++客户端到Java服务器的文件传输

[英]File transfer from C++ client to Java server

I have a c++ client which needs to send a file to a c++ server. 我有一个C ++客户端,需要将文件发送到C ++服务器。 I'm splitting the file to chunks of PACKET_SIZE (=1024) bytes and send them over a TCP socket. 我将文件拆分为PACKET_SIZE(= 1024)个字节,并通过TCP套接字发送它们。 At the server side I read at most PACKET_SIZE bytes to a buffer. 在服务器端,我最多将PACKET_SIZE个字节读到缓冲区。 When the client sends files which are less than PACKET_SIZE, the server receives more bytes than sent. 当客户端发送的文件小于PACKET_SIZE时,服务器接收的字节数大于发送的字节数。 Even when I limit the number of bytes to be exactly the size of the file, the files differ. 即使我将字节数限制为恰好是文件的大小,文件也有所不同。 I know the problem does not have to do with the client because I've tested it with a c++ server and it works flawlessly. 我知道问题与客户端无关,因为我已经使用c ++服务器对其进行了测试,并且可以完美地工作。

Thanks. 谢谢。

Server: 服务器:

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 */}

} }

Client: 客户:

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

Is the sending socket closed at the end of the file, or is the next file streamed over the same socket? 发送套接字是在文件末尾关闭还是下一个文件通过同一套接字流传输? If more than one file is streamed, you could pick up data from the next file if you have the endedness wrong for the file size in recvHeader() , ie you send a file of length 0x0102 and try to read one of length 0x0201. 如果流传输了多个文件,并且如果recvHeader()的文件大小的recvHeader()有误,则可以从下一个文件中提取数据,即,发送一个长度为0x0102的文件并尝试读取一个长度为0x0201的文件。

Other question, why do you provide a max for the first read, but not for the following reads on the same file? 另一个问题,为什么您要为同一文件的第一次读取提供最大值,而不为随后的读取提供最大值?

One issue I see is that it appears that you assume that if the send returns a non-error, that it sent the entire chunk you requested it to send. 我看到的一个问题是,似乎您假设如果发送返回一个非错误,那么它将发送您请求发送的整个块。 This is not necessarily true, especially with stream sockets. 这不一定是正确的,尤其是对于流套接字。 How large are the packets you are sending, and how many? 您要发送的数据包有多少,有多少? The most likely reason this could occur would be if the sndbuf for the socket filled, and your socket _sd is set to non-blocking. 发生这种情况的最可能原因是套接字的sndbuf已填充,并且套接字_sd设置为非阻塞。 I'm not positive (depends on stack implementation), but I believe it could also likely occur if the TCP transmit window was full for your connection, and tcp couldn't enqueue your entire packet. 我不是很乐观(取决于堆栈的实现),但是我认为如果TCP传输窗口已满,并且连接到TCP不能使整个数据包入队,也有可能发生这种情况。

You should probably loop on the send until max is sent. 在发送max之前,您可能应该循环发送。

Thusly: 因此:

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

the code is not complete. 代码不完整。 Eg you have omitted the sending of the filename and the filesize, as well as the parsing of those values. 例如,您省略了文件名和文件大小的发送以及这些值的解析。 Are those values correct? 这些值正确吗? If not first ensure that these values are the right ones before investigating further. 如果不是这样,请在进一步研究之前先确保这些值是正确的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM