rrrrroo
rrrrroo

Reputation: 23

Linux abstract socket refuse connection on SOCK_DGRAM

I am writing a simple client-server app using AF_UNIX sockets, but my code does not work. When I want to send to socket I get transport endpoint not connected error. Any advices?

SERVER:

struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
addr.sun_family=AF_UNIX;
strcpy(addr.sun_path+1,"example");
addr.sun_path[0]=0;
int mysock = socket(AF_UNIX, SOCK_DGRAM, 0);
if((bind(mysock, (struct sockaddr *)&addr,sizeof(addr)))<0)
{
  perror("bind() error");
  return false;
}
if (send(mysock, path, sizeof(path), 0)<0)
{
  perror("send");
}

CLIENT:

struct sockaddr_un addr;
memset(&addr, 0, sizeof(addr));
int mysock = socket(AF_UNIX, SOCK_DGRAM, 0);
if(mysock<0)
{
  perror("socket() error");
  return false;
}
addr.sun_family=AF_UNIX;
strcpy(addr.sun_path+1,"example");
addr.sun_path[0]=0;
if((connect(mysock, (struct sockaddr *)&addr,sizeof(addr)))<0)
{
  perror("connects() error");
  return false;
}
recv(mysock, buf, sizeof(buf),0);
printf("%s\n",buf);

Upvotes: 0

Views: 879

Answers (2)

Gil Hamilton
Gil Hamilton

Reputation: 12357

You haven't connected the server side. Binding a socket to an address establishes the address of the local peer. However, immediately after binding the socket, you're doing a send but you haven't specified a destination. I.e. where is the data to be sent?

Furthermore, Unix domain datagram sockets are different than others in that both sides need to establish a local address before bidirectional data transfer can occur.

So each side needs to create a socket and bind it to an address of their choosing. The client side can then either connect to the server's address (which permanently establishes the destination address), or it may use sendto to specify the destination address for each buffer.

The server will typically use recvfrom to receive data and the client's address, then use sendto to return the response to the client.

For the sake of clarity, this example in python3. Server code:

import socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind(b'\x00server')            # Our address
data, addr = sock.recvfrom(1024)
print("Data:", data)
print("Client Address:", addr)
sock.sendto(data, addr)

Client code:

import socket
sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
sock.bind(b'\x00client')      # Our address
sock.connect(b'\x00server')   # Server's address
data = b"Hello"
sock.send(data)
print("Sent", data)
rdata, saddr = sock.recvfrom(1024)
print("ReturnedData:", rdata)
print("ServerAddr returned:", saddr)

Upvotes: 2

user207421
user207421

Reputation: 310985

transport not connected

You can't use send() on an unconnected UDP socket. You need to either connect() it or use sendto(). This is all documented.

NB What does 'Linux abstract socket' mean? I don't see anything abstract about your code. You are also lacking error-checking on recv(), which needs to be recvfrom() if the socket is unconnected.

Upvotes: 0

Related Questions