2017-02-02 3 views
0

Nach dem Aufbau und die Ausführung der folgenden Probe I nächste Ausgabe erhalten haben:falsche Adresse empfangen von UNIX lokalen Socket (abstract Namensraum)

binden an: echosock
rv: 14 Daten: ‚[[[some ]]]‘sz: 14 remAddrLen: 14

Warum remAddrLen Null ist: 0
Client gesendet? Und die entsprechende entfernte Adresse wurde nicht zurückgegeben?

#include <cstdlib> 
#include <cstdint> 
#include <vector> 
#include <iostream> 
#include <thread> 

namespace {                                                 
const char* SOCK_PATH = "echosock";                                           
const char* TEST_DATA = "[[[SomeData]]]";                                          
} 

int main()                                                  
{                                                    
    pid_t childPid = ::fork();                                             
    if (childPid == 0)                                               
    {                                                   
     std::this_thread::sleep_for(std::chrono::milliseconds(100));  // hack: wait until server is starting reading                       
     const int d = ::socket(AF_UNIX, SOCK_DGRAM, 0);                                      
     if (d == -1)                                               
     {                                                  
      perror("socket");                                             
      return EXIT_FAILURE;                                            
     }                                                  

     struct sockaddr_un locAddr;                                           
     ::memset(&locAddr, 0, sizeof(locAddr));                                        
     locAddr.sun_family = AF_UNIX;                                           
     ::strncpy(locAddr.sun_path + 1, SOCK_PATH, sizeof(locAddr.sun_path) - 1);                                
     const socklen_t locAddrLen = ::strlen(SOCK_PATH) + 1 + sizeof(locAddr.sun_family);                              
     const int rv = ::sendto(d, TEST_DATA, ::strlen(TEST_DATA), 0, reinterpret_cast<sockaddr*>(&locAddr), locAddrLen);                      
     std::cout << "client sent: " << rv << std::endl;                                      
     ::close(d);                                               
    }                                                   
    else if (childPid > 0)                                              
    {                                                   
     const int d = ::socket(AF_UNIX, SOCK_DGRAM, 0);                                      
     if (d == -1)                                               
     {                                                  
      perror("socket");                                             
      return EXIT_FAILURE;                                            
     }                                                  

     std::cout << "bind to: " << SOCK_PATH << std::endl;                                     
     struct sockaddr_un locAddr;                                           
     ::memset(&locAddr, 0, sizeof(locAddr));                                        
     locAddr.sun_family = AF_UNIX;                                           
     ::strncpy(locAddr.sun_path + 1, SOCK_PATH, sizeof(locAddr.sun_path) - 1);                                
     const socklen_t locAddrLen = ::strlen(SOCK_PATH) + 1 + sizeof(locAddr.sun_family);                              
     if (::bind(d, reinterpret_cast<sockaddr*>(&locAddr), locAddrLen) == -1)                                
     {                                                  
      perror("bind");                                             
      ::close(d);                                              
      return EXIT_FAILURE;                                            
     } 
     struct sockaddr_un remAddr;                                           
     socklen_t remAddrLen = sizeof(remAddr);                                        
     std::vector<char> buff(::strlen(TEST_DATA));                                       
     const int rv = ::recvfrom(d, buff.data(), buff.size(), 0, reinterpret_cast<sockaddr*>(&remAddr), &remAddrLen);                       
     std::cout << "rv: " << rv << " data: '";                                        
     std::cout.write(buff.data(), buff.size());                                        
     std::cout << "' sz: " << buff.size() << " remAddrLen: " << remAddrLen << std::endl;                             

     ::close(d);                                               
    }                                                   
    else                                                  
    {                                                   
     perror("fork");                                              
     return EXIT_FAILURE;                                             
    }                                                   

    return EXIT_SUCCESS;                                              
} 

Antwort

0

Ich habe den Grund gefunden:

  1. Client- und Server sollten unterschiedliche Adressen verwenden (auch auf demselben Knoten)
  2. -Client sollte auch binden verwenden.

Corrected Code:

#include <sys/un.h> 
#include <sys/types.h> 
#include <sys/socket.h> 
#include <unistd.h> 

#include <cstdlib> 
#include <cstdint> 
#include <vector> 
#include <iostream> 
#include <thread> 

namespace {                                                 
const char* SOCK_PATH1 = "echosock1";                                           
const char* SOCK_PATH2 = "echosock2";                                           
const char* TEST_DATA = "[[[SomeData]]]";                                          
} 

int main()                                                  
{                                                    
    pid_t childPid = ::fork();                                             
    if (childPid == 0)                                               
    {                                                   
     std::this_thread::sleep_for(std::chrono::milliseconds(100)); // hack: wait until server is starting reading                       
     const int d = ::socket(AF_UNIX, SOCK_DGRAM, 0);                                      
     if (d == -1)                                               
     {                                                  
      perror("socket");                                             
      return EXIT_FAILURE;                                            
     }                                                  

     struct sockaddr_un locAddr;                                           
     ::memset(&locAddr, 0, sizeof(locAddr));                                        
     locAddr.sun_family = AF_UNIX;                                           
     ::strncpy(locAddr.sun_path + 1, SOCK_PATH1, sizeof(locAddr.sun_path) - 1);                                
     const socklen_t locAddrLen = ::strlen(SOCK_PATH1) + 1 + sizeof(locAddr.sun_family);                             

     std::cout << "cl bind to: " << SOCK_PATH1 << std::endl;                                    
     if (::bind(d, reinterpret_cast<sockaddr*>(&locAddr), locAddrLen) == -1)                                
     {                                                  
      perror("bind");                                             
      ::close(d);                                              
      return EXIT_FAILURE;                                            
     }                                                  

     struct sockaddr_un remAddr;                                           
     ::memset(&remAddr, 0, sizeof(remAddr));                                        
     remAddr.sun_family = AF_UNIX;                                           
     ::strncpy(remAddr.sun_path + 1, SOCK_PATH2, sizeof(remAddr.sun_path) - 1);                                
     const socklen_t remAddrLen = ::strlen(SOCK_PATH2) + 1 + sizeof(remAddr.sun_family);                             
     const int rv = ::sendto(d, TEST_DATA, ::strlen(TEST_DATA), 0, reinterpret_cast<sockaddr*>(&remAddr), remAddrLen);                      
     std::cout << "client sent: " << rv << " to " << SOCK_PATH2 << std::endl;                                
     ::close(d);                                               
    } 
    else if (childPid > 0)                                              
    {                                                   
     const int d = ::socket(AF_UNIX, SOCK_DGRAM, 0);                                      
     if (d == -1)                                               
     {                                                  
      perror("socket");                                             
      return EXIT_FAILURE;                                            
     }                                                  

     std::cout << "bind to: " << SOCK_PATH2 << std::endl;                                     
     struct sockaddr_un locAddr;                                           
     ::memset(&locAddr, 0, sizeof(locAddr));                                        
     locAddr.sun_family = AF_UNIX;                                           
     ::strncpy(locAddr.sun_path + 1, SOCK_PATH2, sizeof(locAddr.sun_path) - 1);                                
     const socklen_t locAddrLen = ::strlen(SOCK_PATH2) + 1 + sizeof(locAddr.sun_family);                             
     if (::bind(d, reinterpret_cast<sockaddr*>(&locAddr), locAddrLen) == -1)                                
     {                                                  
      perror("bind");                                             
      ::close(d);                                              
      return EXIT_FAILURE;                                            
     }                                                  

     struct sockaddr_un remAddr;                                           
     socklen_t remAddrLen = sizeof(remAddr);                                        
     std::vector<char> buff(::strlen(TEST_DATA));                                       
     const int rv = ::recvfrom(d, buff.data(), buff.size(), 0, reinterpret_cast<sockaddr*>(&remAddr), &remAddrLen);                       
     std::cout << "rv: " << rv << " data: '";                                        
     std::cout.write(buff.data(), buff.size());                                        
     std::cout << "' sz: " << buff.size() << " remAddrLen: " << remAddrLen << std::endl;                             

     ::close(d);                                               
    }                                                   
    else                                                  
    {                                                   
     perror("fork");                                              
     return EXIT_FAILURE;                                             
    }                                                   

    return EXIT_SUCCESS;                                              
} 
Verwandte Themen