首页 > 解决方案 > C中的服务器向Java中的客户端发送文件,但接收到的文件不完整

问题描述

我正在尝试将文本文件从 C 服务器发送到 Java 客户端。我运行了我的代码,发现我缺少原始文件中的第一个(8 个字符长)单词,但我不知道如何解决这个问题。

C中的服务器:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/stat.h>

#define PORT htons(12221)

void ServeConnection(int sock)
{
    char path[512];
    long dl_of_the_file, sent, sent_in_total, read;
    struct stat fileinfo;
    unsigned char buffer[1024];
    FILE* file;

    printf("Give the path to the file: \n");
    memset(path, 0, 512);
    scanf("%s",path);

    if (stat(path, &fileinfo) < 0)
    {
        printf("Child: I can't obtain information about a file\n");
        return;
    }
    if (fileinfo.st_size == 0)
    {
        printf("Child: filesize 0\n");
        return;
    }

    printf("Child: filesize : %d\n", fileinfo.st_size);

    dl_of_the_file = fileinfo.st_size;
    sent_in_total = 0;
    file = fopen(path, "rb");

    if (file == NULL)
    {
        printf("Child: error at opening a file\n");
        return;
    }

    while (sent_in_total < dl_of_the_file)
    {
        read = fread(buffer, 1, 1024, file);
        sent = send(sock, buffer, read, 0);
        if (read != sent)
            break;
        sent_in_total += sent;
        printf("Child: total sent %ld\n", sent_in_total);
    }

    if (sent_in_total == dl_of_the_file)
    {
        printf("Child: file sent ok\n");
    }
    else
    {
        printf("Child: error at sending a file\n");
    }

    fclose(file);
    return;    
}


int main()
{
    struct sockaddr_in adr;
    socklen_t dladr = sizeof(struct sockaddr_in);
    int sock_listen, sock_client;
    sock_listen = socket(PF_INET, SOCK_STREAM, 0);
    adr.sin_family = AF_INET;
    adr.sin_port = PORT;
    adr.sin_addr.s_addr = INADDR_ANY;
    memset(adr.sin_zero, 0, sizeof(adr.sin_zero));


    if (bind(sock_listen, (struct sockaddr*) &adr, dladr) < 0)
    {
        printf("Parent: bind failed\n");
        return 1;
    }

    listen(sock_listen, 10);
    printf("Server running...\n");

    while(1)
    {
        dladr = sizeof(struct sockaddr_in);
        sock_client = accept(sock_listen, (struct sockaddr*) &adr, &dladr);

        if (sock_client < 0)
        {
            printf("Parent: accept error\n");
            continue;
        }

        printf("Parent: connection from %s:%u\n", 
            inet_ntoa(adr.sin_addr),
            ntohs(adr.sin_port));
        printf("Parent: I'm creating child process\n");


        if (fork() == 0)
        {
            //child
            printf("Child: start serving)\n");
            ServeConnection(sock_client);
            printf("Child: closing socket\n");
            close(sock_client);
            printf("Child: end of the process\n");
            exit(0);
        }
        else
        {
            //parent
            printf("Parent: return to listening)\n");
            continue;
        }

    }
    return 0;
}

和java中的客户端:

package com.company;

import java.net.*;
import java.io.*;

public class Client2 {

    public static void main (String [] args ) throws IOException {
      Socket socket = new Socket("150.254.79.243", 12221);
        System.out.println("Connected");

        int bytesRead;

        int filesize = 999999999;
        byte [] byteArray  = new byte [filesize];

        InputStream is = socket.getInputStream();
        DataInputStream clientData = new DataInputStream(is);
        long size = clientData.readLong();


        FileOutputStream fos = new FileOutputStream("/Users/adh/Desktop/test/test2.txt");
         while ( (bytesRead = clientData.read(byteArray, 0, (int) Math.min(byteArray.length, size))) > -1) {
            fos.write(byteArray, 0, bytesRead);
            size -= bytesRead;

        }

        fos.close();
        is.close();
        socket.close();
    }
}

我试图发送的文件:“你好,你好吗?”

我得到了什么:“你好吗?”

我该如何解决这个问题?

标签: javacclient-server

解决方案


我认为问题出在线路上

long size = clientData.readLong();

根据this,它将读取前 8 个字节,解析为 long 值。看起来您正在尝试使用它来查找输入流的长度,但它不是那样工作的,我认为没有办法获取输入流的长度。通常,您应该首先在这样的代码中发送该信息。

基本上,删除该行并将大小设置为一个较大的值(现在)应该可以解决您的问题,但是您应该在以后的这种情况下练习先发送长度。


推荐阅读