对于socket模式的通信来说,除了常见的TCP/IP套接字还有Unix套接字。不过说Unix套接字是系统上的一个文件,而非主机名和端口,而Unix套接字关闭之后,文件系统上仍然会存在套接字文件,需要在服务端程序启动之前进行删除,它的其他操作和TCP/IP套接字是一样的。下面用一个简单的echo server记录一下Unix套接字的基本使用方法。
server端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 import socketimport sysimport osserver_addr = './uds.sock' try : os.unlink(server_addr) except OSError: if os.path.exists(server_addr): raise sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) print >>sys.stderr, 'Starting up on %s' , server_addrsock.bind(server_addr) sock.listen(5 ) while True : print >>sys.stderr, 'Waiting for connetion...' conn, client_addr = sock.accept() try : print >>sys.stderr, 'connection from ' , client_addr while True : data = conn.recv(6 ) print >>sys.stderr, 'recv data %s' % data if data: print >>sys.stderr, 'echo %s to client' % data conn.sendall(data) else : print >>sys.stderr, 'no data from client' break finally : conn.close()
客户端代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 import socketimport syssock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) server_addr = './uds.sock' print >>sys.stderr, 'connecting to %s' , server_addrtry : sock.connect(server_addr) except socket.error, msg: print >>sys.stderr, msg sys.exit(1 ) try : message = "This is the message. It will be repeated." print >>sys.stderr, 'sending %s' % message sock.sendall(message) amount_received = 0 amount_expected = len (message) while amount_received < amount_expected: data = sock.recv(16 ) amount_received += len (data) print >>sys.stderr, 'received %s' % data finally : print >>sys.stderr, 'closing socket' sock.close()
运行结果:
服务端:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 xing@xing:~/pypractice$ python uds_server.py Starting up on %s ./uds.sock Waiting for connetion... connection from recv data This i echo This i to client recv data s the echo s the to client recv data messag echo messag to client recv data e. It echo e. It to client recv data will b echo will b to client recv data e repe echo e repe to client recv data ated. echo ated. to client recv data no data from client
客户端:
1 2 3 4 5 6 7 xing@xing:~/pypractice$ python uds_client.py connecting to %s ./uds.sock sending This is the message. It will be repeated. received This is the mess received age. It will be received repeated. closing socket
使用Unix套接字需要注意程序是否有权限去读写套接字文件。
Unix套接字最主要的一个用途就是用于进程间通信,为此还有本大部头的书籍《Unix网络编程卷2:进程间通信》,看来还得买来学习一下。
这里有个简单的进程间通信的小例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 import socketimport osparent, child = socket.socketpair() pid = os.fork() if pid: print 'in parent, sending message' child.close() parent.sendall('ping' ) response = parent.recv(1024 ) print 'response from child:' , response parent.close() else : print 'in child, waiting for message' parent.close() message = child.recv(1024 ) print 'message from parent:' , message child.sendall('pong' ) child.close()
运行结果:
1 2 3 4 5 xing@xing:~/pypractice$ python pro.py in parent, sending message in child, waiting for message message from parent: ping response from child: pong
参考链接:https://pymotw.com/2/socket/uds.html