Python编写socket客户端(AF_UNIX)

Python编写socket客户端(AF_UNIX)

文章参考:
https://blog.csdn.net/lwc5411117/article/details/83018252
https://blog.csdn.net/weixin_39258979/article/details/80931464

我们都知道socket本来是为网络通讯设计,可以通过socket方便的实现不同机器之间的通信。当然通过socket也可以实现同一台主机之间的进程通信。
基于socket的框架上发展出一种IPC机制,就是UNIX Domain Socket。虽然网络socket也可用于同一台主机的进程间通讯(通过loopback地址127.0.0.1),但是UNIX Domain Socket用于IPC 更有效率及可靠 :

  • 不需要经过网络协议栈
  • 不需要打包拆包、计算校验和、维护序号和应答等,可靠性更强 UNIX Domain
  • Socket传输效率比通过loopback地址快将近一倍

Socket客户端,Python版本:2.7.5

import socket
import sys
import os
import struct
import json
import threading
 

# 重新写一个类,继承threading.Thread,因为默认的threading.Thread没有返回值,通常socket都需要接收线程返回值
class MyThread(threading.Thread):  
    def __init__(self, func, args=()):  
        super(MyThread, self).__init__()  
        self.func = func  
        self.args = args  
  
    def run(self):  
        self.result = self.func(*self.args)  # 在执行函数的同时,把结果赋值给result,  
        # 然后通过get_result函数获取返回的结果  
  
    def get_result(self):  
        try:  
            return self.result  
        except Exception as e:  
            return None  


UNIX_SOCK_PIPE_PATH = "/tmp/unixsock_proxy.sock"    # 套接字存放路径
 
def clientSocket():
    # 创建套接字
    sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
    if sock == 0:
        print('socket create error')
        return
 
    # 链接服务端
    sock.connect(UNIX_SOCK_PIPE_PATH)
 
    # 发送消息
    msg = 'tell me current time\n'  # 如果此处为json数据,可用json.dumps函数将字典转为json,否则c语言无法读取
    sendRequest(sock, str.encode(msg))
 
    t = MyThread(target=onMessageReceived, args=(sock,))
    t.join()
    t.start()

def sendRequest(sock, data):
    length = len(data)
    buf = struct.pack("i", length) # "big"
    sock.sendall(buf+data)
 
def onMessageReceived(sock):
    #while True:
        data = parseResponse(sock)
        print("{0}\tReceived from client: {1}".format(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(time.time())), bytes.decode(data)))
        sock.close()
    #   break
 
# Parse request of unix socket
# conn: conn handler
def parseResponse(sock):
    lenStr = sock.recv(4)
    length = struct.unpack("i", lenStr) # "big"
    data = sock.recv(length)
    return data
 
if __name__=="__main__":
    clientSocket()

注意两个点:

  • Socket可以发送buffer+json组合数据。
  • 网上很多文档组装buffer时都是用的int.from_bytes()函数,实际上这是Python3的函数。在Python2中,可以使用structo库的pack函数。详细语法可参考PHP中文网

瀑布是河流走投无路时创造的奇迹

你可能感兴趣的:(python,python)