ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

使用AF_UNIX套接字的python asyncore问题

2019-08-27 01:56:55  阅读:254  来源: 互联网

标签:asyncore python sockets unix-socket


我在使用带有AF_UNIX套接字的asyncore时遇到了一些问题.这段代码

import asyncore, socket, os
class testselect(asyncore.dispatcher):

    path = '/tmp/mysocket'

    def __init__(self):

        asyncore.dispatcher.__init__(self)

        self.create_socket(socket.AF_UNIX, socket.SOCK_DGRAM)
        self.bind(self.path)
        self.buffer = 'buffer'

    def handle_connect(self):

        print 'handle_connect'
        pass

    def handle_close(self):
        print 'handle_close'
        if os.path.exists(self.path)       
             os.remove(self.path)
        self.close()

    def handle_read(self):
        print 'handle_read'
        print self.recv(8192)

    def writable(self):
        print 'writable'
        return (len(self.buffer) > 0)

    def handle_write(self):
        print 'handle_write'
        sent = self.send(self.buffer)
        self.buffer = self.buffer[sent:]


    client = testselect()
    asyncore.loop()

如果我执行代码

 $python select_prova.py
 writable
 handle_connect
 handle_write
 handle_close
 $ 

它立即退出,不等待读写.如果我改变代码强制writable()方法返回总是False,它正确等待输入,我可以像这样与socat通信

 $socat readline UNIX:/tmp/mysocket

但仅用于读取(逻辑写入不起作用,因为writable()返回False).我的代码中是否有错误,或者我无法使用asyncore / select()管理AF_UNIX套接字?

解决方法:

注意正如另一个答案所指出的,当您发送数据报时,您需要指定接收器.就目前而言,您的testselect类看起来更像客户端而不是服务器.

查看其中一些asyncore examples以查找可以复制的服务器模式. TimeChannel示例更接近您想要的 – 将socket.AF_INET更改为socket.AF_UNIX并使用套接字路径作为绑定地址,以使其使用UNIX域套接字.

您正在设置socket.SOCK_DGRAM,它通常表示创建UDP INET套接字. Unix域套接字是IPC的一种形式.您应该将其更改为socket.SOCK_STREAM,调用self.listen([backlog]),实现handle_accept()等.

如果您确实打算将SOCK_DGRAM与AF_UNIX一起使用,那么服务器退出的原因是它一旦启动就表明它是可写的,这会导致handle_write运行,立即发送包含’buffer’的数据包.

如果您希望服务器在回复之前等到收到数据包,请在handle_connect或handle_read中设置缓冲区:

    def __init__(self):
        ...
        self.buffer = ''

    def handle_connect(self):
        self.buffer = 'buffer'

现在,当你启动服务器时,它会等到收到来自socat的数据包.

我已经重写了你的例子,让你更喜欢你的工作:

import asyncore, socket, os

class testselect(asyncore.dispatcher):

    path = '/tmp/mysocket'

    def __init__(self):
        asyncore.dispatcher.__init__(self)
        self.create_socket(socket.AF_UNIX, socket.SOCK_STREAM)
        self.set_reuse_addr()
        self.bind(self.path)
        self.listen(5)

    def handle_accept(self):
        client = self.accept()
        if client is None:
            pass
        else:
            handler = testhandler(*client)

class testhandler(asyncore.dispatcher_with_send):

    def __init__(self, sock, addr):
        asyncore.dispatcher_with_send.__init__(self, sock)
        self.addr = addr
        self.buffer = 'greetings'

    def handle_read(self):
        print self.recv(8192)

    def writable(self):
        return (len(self.buffer) > 0)

    def handle_write(self):
        self.send(self.buffer)
        self.buffer = ''

    def handle_close(self):
        self.close()

server = testselect()
try:
    asyncore.loop()
finally:
    if os.path.exists(testselect.path):
        os.unlink(testselect.path)

标签:asyncore,python,sockets,unix-socket
来源: https://codeday.me/bug/20190827/1735797.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有