0

I need to write a tftp client implementation to send a file from a windows phone 8.1 to a piece of hardware. Because I need to be able to support windows 8.1 I need to use the Windows.Networking.Sockets classes.

I'm able to send my Write request package but I am having troubles to receive the ack package (wireshark). This ack package is sent to an "ephemeral port" according to the TFTP specification but the port is blocked according to wireshark.

I know how to use sockets on a specific port but I don't know how to be able to receive ack packages send to different (ephemeral) ports. I need to use the port used for that ack package to continue the TFTP communication.

How would I be able to receive the ACK packages and continue to work on a different port? Do I need to bind the socket to multiple ports? I've been trying to find answers on the microsoft docs and google but other implementations gave me no luck so far.

As reference my current implementation:

    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);
datezZz
  • 11
  • 3

1 Answers1

1

Finally found the issue. Instead of connectAsynch I used getOutputStreamAsynch and now it receives messages on the client socket:

Some code:

  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);
datezZz
  • 11
  • 3