Вопрос

I'm trying to transfer a file using sockets from a C++ application to a Java application. I wrote this simple code in C++ to send the file:

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

On the Java side this is how I write down data received:

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

The result is that the file I receive is correct to a certain point, but it is not complete. Is there anything wrong in my code wither in the Java or in the C++ part? Thanks!

Это было полезно?

Решение

  • UDP doesn't guarantee that all datagrams will arrive.
  • UDP doesn't guarantee that all datagrams will arrive only once.
  • UDP doesn't guarantee that the datagrams that do arrive will be in the sequence that you sent them.

See here.

You are wrong to assume that these rules do not apply just because your sender and receiver are on the same machine.

UDP without any form of additional reliability and sequencing is simply the wrong choice for what you want to do.

You should use TCP (or another reliable transport) rather than UDP.

Другие советы

Just by looking over your code, the problem probably is, that you're write statement is wrong:

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

which should be:

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

Another note: are you closing the FileOutputStream intentionally within the while loop (therefore every time you execute the loop? (this is not really wrong but slower)

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top