locked
Metro app:Client socket data read fail,server at desktop

    Question

  • Hi,

    I am trying to read data from client socket,socket creation,connection every thing is fine,server socket(which is at desktop) is able to send the data,but not able receive the data,when am trying to print receiving data length it is  showing some garbage value,can any one help me.

    I am developing this for metro app using visual studio 11 express,in c++ language.

    can it possible to write  read client socket data for metro app,with two different host or same host? 

    can it possible to make read in client or listen in server as a blocking call ?

    here my code:


        // Save the socket, so subsequent steps can use it.
        CoreApplication::Properties->Insert("clientSocket", socket);

    // Connect to the server 
    task<void> connect(socket->ConnectAsync(ref new HostName("127.0.0.1"),  "27019", SocketProtectionLevel::PlainSocket));
    connect.then([this] (task<void> previousTask)
    {
    try
    {
    StreamSocket^ socket = dynamic_cast<StreamSocket^>(CoreApplication::Properties->Lookup("clientSocket"));

    // Try getting all exceptions from the continuation chain above this point
    previousTask.get();

    NotifyUserFromAsyncThread("hello anil1.....Connected to the server", NotifyType::StatusMessage);

    // Mark the socket as connected. We do not really care about the value of the property, the mere existance means that we are connected.
    CoreApplication::Properties->Insert("connected", PropertyValue::CreateBoolean(true));

    if (CoreApplication::Properties->HasKey("connected"))
    {
    //DataReader^ reader = ref new DataReader(socket->InputStream);
    // Start a receive loop.
    ReceiveStringLoop(reader,socket);
    }
    }
    catch (Exception^ exception)
    {
    //rootPage->NotifyUserFromAsyncThread("Connect failed with error: " + exception->Message, NotifyType::ErrorMessage);
    NotifyUserFromAsyncThread("Connect failed with error: " + exception->Message, NotifyType::ErrorMessage);
    }


    });            

    void MainPage::ReceiveStringLoop(DataReader^ reader,StreamSocket^ socket)
    {

        // Read first 4 bytes (length of the subsequent string).
        task<unsigned int> loadSize(reader->LoadAsync(sizeof(UINT32)));
        loadSize.then([this, reader, socket] (unsigned int size)
        {
    //NotifyUserFromAsyncThread("Received data length: \"" + size + "\"", NotifyType::StatusMessage);
            if (size < sizeof(UINT32))
            {
                // The underlying socket was closed before we were able to read the whole data.
                throw StreamClosedException();
            }

    unsigned int stringLength = reader->ReadUInt32();
            task<unsigned int> loadString(reader->LoadAsync(stringLength));



    NotifyUserFromAsyncThread("Received data length: \"" + stringLength + "\"", NotifyType::StatusMessage);

            return loadString.then([this, reader, stringLength] (unsigned int actualStringLength)
            {
                if (actualStringLength != stringLength)
                {
                    // The underlying socket was closed before we were able to read the whole data.
                    throw StreamClosedException();
                }

                // Display the string on the screen. In most cases the event will be invoked on a non-UI thread.
                NotifyUserFromAsyncThread("Received data: \"" + reader->ReadString(actualStringLength) + "\"", NotifyType::StatusMessage);

            });
        }).then([this, reader, socket] (task<void> previousTask)
        {
            try
            {

                // Try getting all exceptions from the continuation chain above this point
               // previousTask.get();

                // Everything went ok, so try to receive another string. The receive will continue until the stream is broken (i.e. peer closed closed the socket).
                ReceiveStringLoop(reader, socket);

            }
            catch (Exception^ exception)
            {
    //NotifyUserFromAsyncThread("8 hello anil1!!!!!!!!!....am in receivestringloop.", NotifyType::StatusMessage);
                rootPage->NotifyUserFromAsyncThread("Read stream failed with error: " + exception->Message, NotifyType::ErrorMessage);
    // Explicitly close the socket.
                delete socket;
            }
            catch (StreamClosedException&)
            {
                // Do not print anything here - this will usually happen because user closed the client socket.

                // Explicitly close the socket.
                delete socket;
            }
        });
    }




    • Edited by anili147 Tuesday, May 8, 2012 4:59 AM
    Thursday, May 3, 2012 6:38 AM

All replies

  • Hello,

    Would you please provide us the stock stream information. What message did you send from the server and what message did you get from the metro client.

    How about the Win32 application works with your server?

    Best regards,
    Jesse


    Jesse Jiang [MSFT]
    MSDN Community Support | Feedback to us

    Friday, May 4, 2012 6:01 AM
  • Hi Jesse,

    I have written server in win32 which I am trying to connect the client in WinRT, the connection establishment is fine but the client is not able to read the data sent by server. For testing purpose, I have written client in Win32 and connected to the same server and able to send/receive data successfully, but the same is not working in WinRT client. The previous mail code snippet is my WinRT client.

    When I read the stream length :     unsigned int stringLength = reader->ReadUInt32();,  

    stringLength  we are getting as some garbage value.

    Can you please provide a sample for reading the data in client?

    My doubt is, client is not waiting until server sends data, as and when it connects, trying to read data, by that time server has not sent the data.

    My Win32 server sending data is:

    ///////////////////////////////////////////////////////////////////////////////////////////////////


     iResult = getaddrinfo(NULL, "27019", &hints, &result);
     
     // Create a SOCKET for connecting to server
     ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
      // Setup the TCP listening socket
     iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
     
     freeaddrinfo(result);

     iResult = listen(ListenSocket, SOMAXCONN);
      
    MetroSocket  = accept(ListenSocket, NULL, NULL);
        iResult = send( MetroSocket, "SMS Alert", strlen("SMS Alert"), 0 );

    ////////////////////////////////////////////////////////////////////////////////////

    I have multiple doubts in writing client server application using WinRT.

    1. Can we make read call as blocking call like win32? why because my client should block until server sends the data.

    2. Is listen call in server socket blocking cal like accept() in Win32? Does server waits until client connects? I have observed that its not blocking at 

     task<void> startListener(listener->BindServiceNameAsync(ServiceNameForListener->Text));
        startListener.then([this] (task<void> previousTask)

    Control is going from here even client is not yet connected? if it doesn't wait, at which place connection will happen?

    Thanks,

    Anil

    Friday, May 4, 2012 10:22 AM