[vtkusers] vtkSocketCommunicator strange behaviour

Henry Lehmann henry.lehmann at informatik.tu-freiberg.de
Thu Apr 25 08:03:39 EDT 2013


Thanks for reply again.
I now use a char buffer of a fixed size and initialize it to "ABCD...XYZ".
I use it for sending and receiving. However the error still remains.

Henry

Output:
Server:
comm->WaitForConnection(7777)
Receive
Data
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->CloseConnection()

Client:
comm->ConnectTo(localhost, 7777)
Send
Data
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->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();
     char buffer[1024] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
     if (comm->GetIsServer())
     {
         cout << "Receive" << endl;
         std::size_t size;
         comm->Receive(&size, 1, /* remoteHandle */ 1, 0);
         comm->Barrier();
         comm->Receive(&buffer[0], size, /* remoteHandle */ 1, 1);
         comm->Barrier();
         cout << "Data" << endl;
         for (std::size_t i = 0; i < size; ++i)
         {
             cout << int(buffer[i]) << endl;
         }
     }
     else
     {
         cout << "Send" << endl;
         std::size_t size = strlen(buffer);
         comm->Send(&size, 1, /* remoteHandle */ 1, 0);
         comm->Barrier();
         comm->Send(&buffer[0], size, /* remoteHandle */ 1, 1);
         comm->Barrier();
         cout << "Data" << endl;
         for (std::size_t i = 0; i < size; ++i)
         {
             cout << int(buffer[i]) << endl;
         }
     }
     cout << "comm->CloseConnection()" << endl;
     comm->CloseConnection();
     return 0;
}

On 04/25/2013 01:40 PM, Joachim Pouderoux wrote:
> 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 
> <mailto: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 
>>> <mailto: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 <http://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/fb8a5eab/attachment.htm>


More information about the vtkusers mailing list