unix 域套接字 socketpari()

来源:互联网 发布:淘宝如何购买百度云 编辑:程序博客网 时间:2024/05/22 17:14

一、UNIX Domain Socket IPC 

socket API原本是为网络通讯设计的,但后来在socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC更有效率:不需要经过网络协议栈,不需要打包拆包、计算校验和、维护序号和应答等,只是将应用层数据从一个进程拷贝到另一个进程。UNIX域套接字与TCP套接字相比较,在同一台主机的传输速度前者是后者的两倍。这是因为,IPC机制本质上是可靠的通讯,而网络协议是为不可靠的通讯设计的。UNIX Domain Socket也提供面向流和面向数据包两种API接口,类似于TCP和UDP,但是面向消息的UNIXDomain Socket也是可靠的,消息既不会丢失也不会顺序错乱。

使用UNIX Domain Socket的过程和网络socket十分相似,也要先调用socket()创建一个socket文件描述符,address family指定为AF_UNIX,type可以选择SOCK_DGRAM或SOCK_STREAM,protocol参数仍然指定为0即可。 

UNIX Domain Socket与网络socket编程最明显的不同在于地址格式不同,用结构体sockaddr_un表示,网络编程的socket地址是IP地址加端口号,而UNIX Domain Socket的地址是一个socket类型的文件在 文件系统中的路径 ,这个socket文件由bind()调用创建,如果调用bind()时该文件已存在,则bind()错误返回。

unix-socket-c.py

#!/usr/bin/env pythonimport socketimport osimport timeSERVER_PATH = "/tmp/python_unix_socket_server" def run_unix_domain_socket_server():    if os.path.exists(SERVER_PATH):        os.remove( SERVER_PATH )         print "starting unix domain socket server."    server = socket.socket( socket.AF_UNIX, socket.SOCK_DGRAM )    server.bind(SERVER_PATH)         print "Listening on path: %s" %SERVER_PATH    while True:        datagram = server.recv( 1024 )        if not datagram:            break        else:            print "-" * 20            print datagram        if "DONE" == datagram:            break    print "-" * 20    print "Server is shutting down now..."    server.close()    os.remove(SERVER_PATH)    print "Server shutdown and path removed."if __name__ == '__main__':    run_unix_domain_socket_server()

unix-socket-s.py

#!/usr/bin/env python# Python Network Programming Cookbook -- Chapter - 3# This program is optimized for Python 2.7.# It may run on any other version with/without modifications.import socketimport sysSERVER_PATH = "/tmp/python_unix_socket_server"def run_unix_domain_socket_client():    """ Run "a Unix domain socket client """    sock = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)        # Connect the socket to the path where the server is listening    server_address = SERVER_PATH     print "connecting to %s" % server_address    try:        sock.connect(server_address)    except socket.error, msg:        print >>sys.stderr, msg        sys.exit(1)        try:        message = "This is the message.  This will be echoed back!"        print  "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 "Closing client"        sock.close()if __name__ == '__main__':    run_unix_domain_socket_client()

socket.socketpair()

#!/usr/bin/env python#--coding:utf8--import socketimport osBUFSIZE = 1024def test_socketpair():    """ Test Unix socketpair"""    parent, child = socket.socketpair()    print("os.getpgid:%d"%os.getpid())    print('socketpair:parent:')    print parent    print('socketpair:child:')    print child    pid = os.fork()    print "pid:%d"%pid    try:        if pid:            print "[if pid]pid:%d"%pid            print "@Parent, sending message..."            child.close()            parent.sendall("Hello from parent!")            response = parent.recv(BUFSIZE)            print "Response from child:", response            parent.close()        else:            print "[else]pid:%d"%pid            print "@Child, waiting for message from parent"            parent.close()            message = child.recv(BUFSIZE)            print "Message from parent:", message            child.sendall("Hello from child!!")            child.close()    except Exception, err:        print "Error: %s" %errif __name__ == '__main__':    test_socketpair()




0 0
原创粉丝点击