[vtkusers] vtkSocketCommunicator strange behaviour

Joachim Pouderoux joachim.pouderoux at kitware.com
Thu Apr 25 07:40:08 EDT 2013


Once again. Do not trust str.c_str(), it is here valid only during the call
of the function. Try to copy it into a char* and send this buffer instead.

Joachim

Le 25 avr. 2013 à 12:49, Henry Lehmann <
henry.lehmann at informatik.tu-freiberg.de> a écrit :

 Thanks for your reply.

I changed the program, but the error remains the same.
I put the Barrier inside the if-else-scopes so the local variables will
not get destroyed until the barrier is reached by all
processes.

I even put a barrier behind the send of the size, so that
the size is send/received correctly before the string buffers
for receiving the strings are created.

I changed the example to send the same string 2 times.
For the second time it works and for the first time
the wrong data always is at the same position.

Henry

New Output:
Server:
comm->WaitForConnection(7777)
Receive
comm->Barrier()
comm->Barrier()
Data
65, 65
66, 66
67, 67
68, 68
69, 69
70, 70
71, 71
72, 72
1, 73
0, 74
0, 75
0, 76
77, 77
78, 78
79, 79
80, 80
81, 81
82, 82
83, 83
84, 84
85, 85
86, 86
87, 87
88, 88
89, 89
90, 90
comm->CloseConnection()

Client:
comm->ConnectTo(localhost, 7777)
Send
comm->Barrier()
comm->Barrier()
Data
65, 65
66, 66
67, 67
68, 68
69, 69
70, 70
71, 71
72, 72
73, 73
74, 74
75, 75
76, 76
77, 77
78, 78
79, 79
80, 80
81, 81
82, 82
83, 83
84, 84
85, 85
86, 86
87, 87
88, 88
89, 89
90, 90
comm->CloseConnection()

Updated source code:
#include <vtkNew.h>
#include <vtkSocketCommunicator.h>
#include <vtkClientServerStream.h>
#include <iostream>
#include <string>
int main(int argc, char *args[])
{
    using namespace std;

    vtkNew<vtkSocketCommunicator> comm;
    comm->SetPerformHandshake(1);
    if (argc == 1)
    {
        cout << "comm->WaitForConnection(7777)" << endl;
        comm->WaitForConnection(7777);
    }
    else if (argc == 2)
    {
        cout << "comm->ConnectTo(localhost, 7777)" << endl;
        comm->ConnectTo("localhost", 7777);
    }
    comm->Handshake();
    comm->Barrier();
    if (comm->GetIsServer())
    {
        cout << "Receive" << endl;

        std::size_t size = 0;
        comm->Receive(&size, 1, /* remoteHandle */ 1, 0);
        cout << "comm->Barrier()" << endl;
        comm->Barrier();

        std::string str1(size, '\n');
        std::string str2(size, '\n');
        comm->Receive(&str1[0], size, /* remoteHandle */ 1, 1);
        comm->Receive(&str2[0], size, /* remoteHandle */ 1, 2);

        cout << "comm->Barrier()" << endl;
        comm->Barrier();
        cout << "Data" << endl;
        for (std::size_t i = 0; i < size; ++i)
        {
            cout << int(str1[i]) << ", " << int(str2[i]) << endl;
        }
    }
    else
    {
        cout << "Send" << endl;
        std::string str1(args[1]);
        std::string str2(args[1]);
        std::size_t size = str1.size();
        comm->Send(&size, 1, /* remoteHandle */ 1, 0);
        cout << "comm->Barrier()" << endl;
        comm->Barrier();

        comm->Send(str1.c_str(), size, /* remoteHandle */ 1, 1);
        comm->Send(str2.c_str(), size, /* remoteHandle */ 1, 2);

        cout << "comm->Barrier()" << endl;
        comm->Barrier();
        cout << "Data" << endl;
        for (std::size_t i = 0; i < size; ++i)
        {
            cout << int(str1[i]) << ", " << int(str2[i]) << endl;
        }
    }
    cout << "comm->CloseConnection()" << endl;
    comm->CloseConnection();
    return 0;
}


The new source code is:

On 04/25/2013 12:20 PM, Joachim Pouderoux wrote:

 I did not try your example yet but I think the issue is due to your local
src.c_str() which is destroyed before the send action is really performed
(send is a asynchronous function).
 So you can try something like :

else
    {
        std::string str(args[1]);
        std::size_t size = str.size();
        const char *s = str.c_str();
        comm->Send(&size, 1, /* remoteHandle */ 1, 0);
        comm->Send(s, size, /* remoteHandle */ 1, 1);
        cout << "Send" << endl;
        cout << str << endl;
        cout << size << endl;
        for (std::size_t i = 0; i < size; ++i)
        {
            cout << int(str[i]) << endl;
        }
        cout << "server comm->Barrier()" << endl;
        comm->Barrier();
    }


 Regads,

*Joachim Pouderoux*

*PhD, R&D Enginee*r
*Kitware SAS <http://www.kitware.fr>*



2013/4/25 Henry Lehmann <henry.lehmann at informatik.tu-freiberg.de>

> Hello,
>
> I am playing around with vtkSocketCommunicator. I want to send integral
> data types and
> wrote a program to get myself into this topic. The source is at the end.
> If the program is started without command line arguments,
> vtkSocketCommunicator
> goes into server mode and waits for a connection at port 7777. If it is
> started
> with one command line argument, the string is send to the server who
> displays it in the terminal. However, the data is not transmitted
> correctly.
>
> Consider this example:
> At first start in server mode tp receive data:
> $ ./program
> Secondly start in client mode and send data:
> $ ./program ABCDEFGHIJKLMNOPQRSTUVWXYZ
>
> The output of the programs is as follows:
>
> Server:
> comm->WaitForConnection(7777)
> Receive
> ABCDEFGH???? MNOPQRSTUVWXYZ
> 26
> 65
> 66
> 67
> 68
> 69
> 70
> 71
> 72
> 1
> 0
> 0
> 0
> 77
> 78
> 79
> 80
> 81
> 82
> 83
> 84
> 85
> 86
> 87
> 88
> 89
> 90
> comm->Barrier()
> comm->CloseConnection()
>
> Client:
> comm->ConnectTo(localhost, 7777)
> Send
> ABCDEFGHIJKLMNOPQRSTUVWXYZ
> 26
> 65
> 66
> 67
> 68
> 69
> 70
> 71
> 72
> 73
> 74
> 75
> 76
> 77
> 78
> 79
> 80
> 81
> 82
> 83
> 84
> 85
> 86
> 87
> 88
> 89
> 90
> comm->Barrier()
> comm->CloseConnection()
>
> As you can see the data is not transmitted correctly and the numbers
> 73, 74, 75, 76 are replaced by 1, 0, 0, 0.
> What am i doing wrong? Am i using this class not as intended?
>
> Thanks in advance,
> Henry.
>
> Source Code:
>
> #include <vtkNew.h>
> #include <vtkSocketCommunicator.h>
> #include <vtkClientServerStream.h>
> #include <iostream>
> #include <string>
> int main(int argc, char *args[])
> {
>     using namespace std;
>
>     vtkNew<vtkSocketCommunicator> comm;
>     comm->SetPerformHandshake(1);
>     if (argc == 1)
>     {
>         cout << "comm->WaitForConnection(7777)" << endl;
>         comm->WaitForConnection(7777);
>     }
>     else if (argc == 2)
>     {
>         cout << "comm->ConnectTo(localhost, 7777)" << endl;
>         comm->ConnectTo("localhost", 7777);
>     }
>     comm->Handshake();
>     comm->Barrier();
>     if (comm->GetIsServer())
>     {
>         std::size_t size = 0;
>         comm->Receive(&size, 1, /* remoteHandle */ 1, 0);
>         std::string str(size, '\n');
>         comm->Receive(&str[0], size, /* remoteHandle */ 1, 1);
>         cout << "Receive" << endl;
>         cout << str << endl;
>         cout << size << endl;
>         for (std::size_t i = 0; i < size; ++i)
>         {
>             cout << int(str[i]) << endl;
>         }
>     }
>     else
>     {
>         std::string str(args[1]);
>         std::size_t size = str.size();
>         comm->Send(&size, 1, /* remoteHandle */ 1, 0);
>         comm->Send(str.c_str(), size, /* remoteHandle */ 1, 1);
>         cout << "Send" << endl;
>         cout << str << endl;
>         cout << size << endl;
>         for (std::size_t i = 0; i < size; ++i)
>         {
>             cout << int(str[i]) << endl;
>         }
>     }
>     cout << "comm->Barrier()" << endl;
>     comm->Barrier();
>     cout << "comm->CloseConnection()" << endl;
>     comm->CloseConnection();
>     return 0;
> }
>
> _______________________________________________
> Powered by www.kitware.com
>
> Visit other Kitware open-source projects at
> http://www.kitware.com/opensource/opensource.html
>
> Please keep messages on-topic and check the VTK FAQ at:
> http://www.vtk.org/Wiki/VTK_FAQ
>
> Follow this link to subscribe/unsubscribe:
> http://www.vtk.org/mailman/listinfo/vtkusers
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.vtk.org/pipermail/vtkusers/attachments/20130425/db743a48/attachment.htm>


More information about the vtkusers mailing list