0

我正在尝试使用套接字将文件从 C++ 应用程序传输到 Java 应用程序。我用 C++ 编写了这个简单的代码来发送文件:

int main() {
    int sock;
    struct sockaddr_in sa;
    char* memblock;

    /* Create socket on which to send. */
    sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
    if (sock < 0) {
        printf("opening datagram socket");
        exit(1);
    }

    /* Construct name of socket to send to. */
    sa.sin_family = AF_INET;
    sa.sin_addr.s_addr = htonl(0x7F000001);
    sa.sin_port = htons(4444);

    /* Send messages. */
    FILE *file;
    unsigned long fileLength = 0;

    file = fopen(FILE_PATH, "rb");
    if (!file) {
        printf("Error opening the file.\n");
        return 1;
    }

    // Get file length.
    fseek(file, 0, SEEK_END);
    fileLength = ftell(file);
    printf("File length is: %d.\n", fileLength);
    fseek(file, 0, SEEK_SET);

    memblock = (char*)malloc(sizeof(char)*fileLength);
    if (memblock == NULL) {fputs ("Memory error",stderr); exit(2);}

    // copy the file into the buffer:
    int result = fread(memblock, 1, fileLength, file);
    if (result != fileLength) {fputs ("Reading error", stderr); exit(3);}

    int pos = 0;
    char* pMemblock = memblock;
    while (pos < fileLength) {
        int sent = sendto(sock, pMemblock, 80, 0, (struct sockaddr*)&sa, sizeof sa);
        if (sent < 0)
            printf("Error sending datagram message.\n");
        else printf("Sent %d.\n", sent);
        pos += 80;
        pMemblock += 80;
    }

    delete memblock;
    fclose(file);

    close(sock);
    return 0;
}

在 Java 方面,这就是我写下收到的数据的方式:

while (true) {
                receiveData = new byte[300];
                receivedPacket = new DatagramPacket(receiveData, receiveData.length);
                serverSocket.receive(receivedPacket);
                try {
                    fou = new FileOutputStream(<filename>, true);
                } catch (FileNotFoundException e1) {
                    e1.printStackTrace();
                }
                fou.write(receivedPacket.getData(), 0, 80);
                fou.close();
            }

结果是我收到的文件在一定程度上是正确的,但并不完整。我的 Java 代码或 C++ 部分的代码有什么问题吗?谢谢!

4

2 回答 2

4
  • UDP 不保证所有数据报都会到达。
  • UDP 不保证所有数据报只会到达一次。
  • UDP 不保证到达的数据报将按照您发送它们的顺序。

这里

你错误地认为这些规则不适用仅仅因为你的发送者和接收者在同一台机器上。

没有任何形式的额外可靠性和排序的 UDP 只是您想要做的错误选择。

您应该使用 TCP(或其他可靠传输)而不是 UDP。

于 2011-02-23T11:45:45.187 回答
0

只需查看您的代码,问题可能是,您的 write 语句是错误的:

fou.write(receivedPacket.getData(), 0, 80);

应该是:

fou.write(receivedPacket.getData(), 0, receivedPacket.getLength());

另一个注意事项:您是否在 while 循环内有意关闭 FileOutputStream (因此每次执行循环时?(这并不是真正的错误,但速度较慢)

于 2011-02-23T11:03:11.087 回答