您的位置:首页 > 编程语言 > PHP开发

unix 域套接字 socketpari()

2016-03-17 10:34 691 查看
一、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 python

import socket
import os
import time

SERVER_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 socket
import sys

SERVER_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 socket
import os
BUFSIZE = 1024
def 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" %err
if __name__ == '__main__':
test_socketpair()
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: