[在此处输入图像描述][1]我已经搜索了解决方案,但没有一个对我有效,有人能帮助我理解我可能做错了什么,或者我在代码中误解了什么,处理不当。
例如,应该接收的文件大小是3656713,服务器上接收的实际大小是3656464。
在我的代码缓冲区中,大小是一个宏,它被设置为4096,我认为这无关紧要,因为我试过使用不同的数字,如256、1024等,
我已经附上了客户端和服务器代码。
这是正在发送媒体文件的客户端:

    while(1){
        //char buff[BUFFER_SIZE]={0};
        memset(buff, 0, BUFFER_SIZE);
        while(!feof(fp)){
            int nread = fread(buff, 1, BUFFER_SIZE, fp);
            __android_log_print(ANDROID_LOG_INFO, "Native", "%d nread %d\n", ++i, nread);
            if(nread == 0){
                __android_log_print(ANDROID_LOG_INFO, "Native", "Something went wrong while reading the file");
                break;
            }
            if(nread > 0){
                int totalWritten = 0;
                do {
                    int actualWritten;
                    actualWritten = write (sockfd, buff + totalWritten, nread - totalWritten);
                    //actualWritten = send (sockfd, buff + totalWritten, nread - totalWritten, 0);
                    if( actualWritten == - 1 ) {
                        __android_log_print(ANDROID_LOG_INFO, "Native", "Unable to write to socket \n");
                        finalStatus = false;
                        break;
                    }
                    totalWritten += actualWritten;
                } while( totalWritten < nread );
            }
            memset(buff, 0, BUFFER_SIZE);
            //usleep(2);
        }
        if(feof(fp)){
            __android_log_print(ANDROID_LOG_INFO, "Native", "End of the file reached");
            EOFReached = true;
            fclose(fp);
        }
        if(ferror(fp)){
            fclose(fp);
            __android_log_print(ANDROID_LOG_INFO, "Native", "Something went wrong while reading the file content");
        }
        break;
    }

这是接收媒体文件的服务器:
 buffer = (char *)malloc(BUFFER_SIZE);
 while((bytesReceived = read(sockfd, buffer, BUFFER_SIZE)) > 0){
     receivedBytes = receivedBytes + bytesReceived;
     printf("%d : Actual size : %d Received size : %d\n", ++i, actualSizeOfTheFile, receivedBytes);
     if(strncmp(buffer, "MYNEWSTRANSFERCOMPLETE", 22) == 0){
         fclose(fp);
         printf("Closed the file as server received the command : %s\n", buffer);
         break;
     }else{
         //printf("%d Bytes recived %d and the data is %s\n", ++i, bytesReceived, buffer);
         fwrite(buffer, 1, bytesReceived, fp);
     }
     memset(buffer, '\0', BUFFER_SIZE);
 }
 printf("Final string received from client is %s\n", buffer);
 memset(buffer, '\0', BUFFER_SIZE);
 printf("Total bytes received from client is :::::%d", receivedBytes);
 if((bytesReceived = read(sockfd, buffer, BUFFER_SIZE)) > 0){
     printf("Final string received from client is %s\n", buffer);
     if((write(sockfd, "You can close the socket", 24)) > 0){
         printf("Acknowledging the client to confirming for closing the connection\n");
     }else{
         printf("Unable to acknowledge the client on close confirmation of the connection\n");
     }
 }else{
     printf("Socket might have been closed by the client\n\n");
 }

我的问题是我正试图使用“C”通过套接字将媒体文件从Android客户端传输到Linux服务器。早些时候,当我开始简单的文件写入和读取媒体文件接收和播放没有任何问题。
但突然间,我发现Linux服务器上的最终接收文件中遗漏了一些数据。
因为我无法在这里添加粘贴日志语句的屏幕快照`
客户端日志
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:889 nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:totalWritten:4096,来自nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:890 nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:totalWritten:4096,来自nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:891 nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:totalWritten:4096,来自nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:892 nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:totalWritten:4096,来自nread 4096
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:893 nread 3081
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:totalwrited:3081,来自nread 3081
05-15 18:59:08.072 30084-30084/com.example.user.resumablesample I/Native:到达文件结尾
05-15 19:04:22.387 30084-30094/com.example.user.resumablesample W/art:挂起所有线程花费:7.375ms
服务器日志
2513:实际大小:3656713接收大小:3644423接收字节:1408
2514:实际大小:3656713接收大小:3645831接收字节:1408
2515:实际大小:3656713接收大小:3647239接收字节:1408
2516:实际大小:3656713接收大小:3648647接收字节:1408
2517:实际大小:3656713接收大小:3650055接收字节:1408
2518:实际大小:3656713接收大小:3651463接收字节:1408
2519:实际大小:3656713接收大小:3652871接收字节:1408
2520:实际大小:3656713接收大小:3654279接收字节:1408
2521:实际大小:3656713接收大小:3655687接收字节:1408
2522:实际大小:3656713接收大小:3656464接收字节:777
服务器上的文件列表
-rw-r--r--1魔术拉玛娜魔术拉玛娜3653632 5月15日13:29 mynews_4zuigxb5nh149485494443.mp4
`
我注意到客户机日志中最后一个3081字节的数据块已经被传输,但是在我列出的最后一个文件中丢失了相同数量的数据。最后的文件大小是3653632,但假设是3656713,比最后一个块中传输的文件多3081字节

最佳答案

if(strncmp(buffer, "MYNEWSTRANSFERCOMPLETE", 22) == 0){

问题就在这里。你不能把它当作缓冲区中的第一件事和唯一的事。TCP是一种流式协议,它可以按照自己喜欢的任何方式将数据传递给接收应用程序,包括一次传递一个字节,或合并缓冲区,或两者之间的任何内容,只要它准确地以正确的顺序传递所有数据一次。
我也会注意到你实际上并没有把这个字符串发送到任何地方。
类似地
if((write(sockfd, "You can close the socket", 24)) > 0){

而且不能保证所有这些都是离散地接收的。我还将注意到,您实际上并没有在任何地方接收到这些数据。
您必须在文件之前传输文件大小,或者在不使用任何应用程序协议发送文件后关闭套接字。

10-08 13:50