Как прослушивать пакеты ACK на эфемерных портах

Мне нужно написать реализацию клиента tftp для отправки файла с телефона Windows 8.1 на аппаратное обеспечение. Поскольку мне нужна поддержка Windows 8.1, мне нужно использовать Классы Windows.Networking.Sockets.

Я могу отправить пакет запроса на запись, но у меня возникают проблемы с получением пакета подтверждения (wireshark< /а>). Этот пакет подтверждения отправляется на «временный порт» в соответствии со спецификацией TFTP, но порт заблокирован в соответствии с wirehark.

Я знаю, как использовать сокеты на определенном порту, но я не знаю, как получить пакеты подтверждения, отправленные на разные (эфемерные) порты. Мне нужно использовать порт, используемый для этого пакета ack, чтобы продолжить связь TFTP.

Как я смогу получать пакеты ACK и продолжать работать на другом порту? Нужно ли привязывать сокет к нескольким портам? Я пытался найти ответы на документы Microsoft и Google, но другие реализации пока не дали мне удачи.

В качестве ссылки на мою текущую реализацию:

    try {
        hostName = new Windows.Networking.HostName(currentIP);
    } catch (error) {
        WinJS.log && WinJS.log("Error: Invalid host name.", "sample", "error");
        return;
    }

    socketsSample.clientSocket = new Windows.Networking.Sockets.DatagramSocket();
    socketsSample.clientSocket.addEventListener("messagereceived", onMessageReceived);
    socketsSample.clientSocket.bindEndpointAsync(new Windows.Networking.HostName(hostName), currentPort);

    WinJS.log && WinJS.log("Client: connection started.", "sample", "status");
    socketsSample.clientSocket.connectAsync(hostName, serviceName).done(function () {
        WinJS.log && WinJS.log("Client: connection completed.", "sample", "status");
        socketsSample.connected = true;
        var remoteFile = "test.txt";
        var tftpMode = Modes.Octet;
        var sndBuffer = createRequestPacket(Opcodes.Write, remoteFile, tftpMode);

        if (!socketsSample.clientDataWriter) {
            socketsSample.clientDataWriter =
                new Windows.Storage.Streams.DataWriter(socketsSample.clientSocket.outputStream);
        }

        var writer = socketsSample.clientDataWriter;
        var reader;
        var stream;

        writer.writeBytes(sndBuffer);

        // The call to store async sends the actual contents of the writer 
        // to the backing stream.
        writer.storeAsync().then(function () {
            // For the in-memory stream implementation we are using, the flushAsync call 
            // is superfluous, but other types of streams may require it.
            return writer.flushAsync();
        });
    }, onError);

person datezZz    schedule 23.02.2016    source источник


Ответы (1)


Наконец нашел проблему. Вместо connectAsynch я использовал getOutputStreamAsynch и теперь он получает сообщения на клиентский сокет:

Некоторый код:

  tftpSocket.clientSocket.getOutputStreamAsync(new Windows.Networking.HostName(self.hostName), tftpSocket.serviceNameConnect).then(function (stream) {
        console.log("Client: connection completed.", "sample", "status");
        var writer = new Windows.Storage.Streams.DataWriter(stream); //use the stream that was created when calling getOutputStreamAsync
        tftpSocket.clientDataWriter = writer; //keep the writer in case we need to close sockets we also close the writer

        writer.writeBytes(sndBytes);

        // The call to store async sends the actual contents of the writer
        // to the backing stream.
        writer.storeAsync().then(function () {
            // For the in-memory stream implementation we are using, the flushAsync call
            // is superfluous, but other types of streams may require it.
            return writer.flushAsync();
        });
    }, self.onError);
person datezZz    schedule 26.02.2016