Hello,
I want to connect the UNIXDomain datagram socket (client -> address
should be bound to dgram socket) - the server doesn't get a correct
peer address (sun_family and sun_path have no valid value after calling
recvfrom).
so sending a message back to the peer will fail.
For UDP sockets it works - is it not supported by UNIXDomain sockets?
with best regards,
Oliver
#include <iostream>
#include <cstdlib>
#include <stdexcept>
#include <sys/un.h>
#include <sys/socket.h>
int main( int argc, char *argv[])
{
try
{
if ( argc > 1)
{
sockaddr_un un;
un.sun_family = PF_LOCAL;
::strncpy(
un.sun_path,
"/tmp/ud_server",
sizeof(un.sun_path) - 1);
int hndl = -1;
if ( ( hndl = ::socket( PF_LOCAL, SOCK_DGRAM, 0) ) < 0)
throw std::runtime_error( ::strerror( errno) );
if ( ::bind(
hndl,
reinterpret_cast< sockaddr * >( & un),
sizeof un) < 0)
throw std::runtime_error( ::strerror( errno) );
while ( true)
{
sockaddr_un peer;
char buf[1024];
socklen_t len;
int n = 0;
if ( ( n = ::recvfrom(
hndl,
buf,
sizeof buf,
0,
reinterpret_cast< sockaddr * >(
& peer),
& len) ) < 0)
throw std::runtime_error( ::strerror( errno) );
std::cout << "PF_LOCAL = " << peer.sun_family << std::endl; // is 0
std::cout << "path = " << peer.sun_path << std::endl; // zero
if ( ::sendto(
hndl,
buf,
n,
0,
reinterpret_cast< sockaddr * >(
& peer),
sizeof peer) < 0)
throw std::runtime_error( ::strerror( errno) );
}
}
else
{
sockaddr_un un;
un.sun_family = PF_LOCAL;
::strncpy(
un.sun_path,
"/tmp/ud_server",
sizeof(un.sun_path) - 1);
int hndl = -1;
if ( ( hndl = ::socket( PF_LOCAL, SOCK_DGRAM, 0) ) < 0)
throw std::runtime_error( ::strerror( errno) );
if ( ::connect( hndl, reinterpret_cast< sockaddr * >( & un), sizeof
un) < 0)
throw std::runtime_error( ::strerror( errno) );
if ( ::write( hndl, "ABC", 3) < 0)
throw std::runtime_error( ::strerror( errno) );
char buf[1024];
int n = 0;
if ( ( n = ::read( hndl, buf, 3) ) < 0)
throw std::runtime_error( ::strerror( errno) );
std::cout << std::string( buf, 0, n) << std::endl;
}
return EXIT_SUCCESS;
}
catch ( std::exception const& e)
{ std::cerr << e.what() << std::endl; }
catch (...)
{ std::cerr << "unhandled exception" << std::endl; }
}
|