Reputation: 1
I'm very new to all of this, but what is the argument or "bytes-like object" needed for .bind()? I read that "the address argument to .bind() and .connect() is the path of the Unix socket file" on this website from 2007: https://utcc.utoronto.ca/~cks/space/blog/python/UnixDomainSockets
I also read this: "After the socket descriptor is created, the bind() API gets a unique name for the socket. The name space for UNIX domain sockets consists of path names. When a sockets program calls the bind() API, an entry is created in the file system directory. If the path name already exists, the bind() fails. Thus, a UNIX domain socket program should always call an unlink() API to remove the directory entry when it ends." https://www.ibm.com/docs/en/i/7.3?topic=families-using-af-unix-address-family
But I still can't find the actual syntax on how to create this path or if I need to change permissions to create this file in my directory?
Here is the beginning snippet of server.py:
import socket
host = "127.0.0.1"
port = 5006
with socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) as s:
s.bind((host, port))
print(f"Starting server on {host}, port{port}")
s.listen()
conn, addr = s.accept()
And here is the beginning snippet of client.py:
import socket
host = "127.0.0.1"
port = 5006
with socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) as s:
s.connect((host,port))
When I run it in WSL, I get this error:
s.bind((host, port)) TypeError: a bytes-like object is required, not 'tuple'
Basically, I initially began this project using SOCK_STREAM and AF_INET and got it working; but now I want to use SOCK_SEQPACKET, so I have to use AF_UNIX. The tuple (host,port) is a relic from AF_INET, but I don't know what to replace it with and the example code online is in C, not Python.
Upvotes: 0
Views: 51
Reputation: 312390
You cannot use a (host, port)
tuple with an AF_UNIX
socket. Like the documentation you provided in your question says:
The name space for UNIX domain sockets consists of path names. When a sockets program calls the bind() API, an entry is created in the file system directory. If the path name already exists, the bind() fails.
Unix domain sockets bind to filesystem paths. You don't need to pre-create anything (well, you need to make sure that the directory in which you are creating the socket exists, I guess), but you do need to remove the socket when you're done.
Example server:
import os
import socket
path = "./server.sock"
try:
with socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) as s:
s.bind(path)
print(f"Starting server on {path}")
s.listen()
while True:
conn, addr = s.accept()
req = conn.recv(1024)
print("received:", req)
conn.send(b"thanks!")
conn.close()
finally:
os.remove(path)
Example client:
import socket
path = "./server.sock"
with socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET) as s:
s.connect(path)
s.send(b"hello!")
res = s.recv(1024)
print(res)
Upvotes: 1