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は、すべてのデータグラムが1回だけ到着することを保証するものではありません。
  • UDPは、到着するデータグラムが送信した順序になることを保証しません。

ここを参照してください。

送信者と受信者が同じマシン上にあるという理由だけで、これらのルールが適用されないと考えるのは誤りです。

信頼性と順序付けを追加しないUDPは、やりたいことに対して単に間違った選択です。

UDPではなくTCP(または別の信頼できるトランスポート)を使用する必要があります。

于 2011-02-23T11:45:45.187 に答える
0

コードを調べるだけで、問題はおそらく、ステートメントの記述が間違っていることです。

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

これは次のようになります。

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

別の注意:whileループ内でFileOutputStreamを意図的に閉じていますか(したがって、ループを実行するたびに?(これは実際には間違っていませんが、遅くなります)

于 2011-02-23T11:03:11.087 に答える