java - C中的服务器向Java中的客户端发送文件,但接收到的文件不完整

标签 java c client-server

我正在尝试将文本文件从 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();
    }
}

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

我得到的是:“你好吗?”

如何解决这个问题?

最佳答案

我认为问题出在线路上

long size = clientData.readLong();

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

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

关于java - C中的服务器向Java中的客户端发送文件,但接收到的文件不完整,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59228300/

相关文章:

c - 在 C 中使用 UDP 发送数据包并测量耗时

java - 在 JOptionPane 中放一个 gif

java - ProcessBuilder 没有正确执行 Java 类文件

c - 如何将匿名字符串文字传递给函数?

c - 右下对角打印二维数组

tcp 应用程序退出总是会发送 FIN 吗?

java - 我应该采用哪种类型的列表来从另​​一个表中加入(内部)2 个表

java - 当我 tar 一个文件时,它的抛出异常为 "is too long ( > 100 bytes) TarArchiveOutputStream"

c - 如何从 SAP Classic RFC API 迁移到 Netweaver RFC API

java - 服务器提供实时游戏状态更新