Raspberry pi 版权所有。 允许以源代码和二进制形式重新分发和使用 前提是上述版权声明和本段 以所有此类形式复制,且任何文件, 广告材料,以及与此相关的其他材料 分发和使用确认软件已开发 由linux-projects.org发布。名称 linux-projects.or

Raspberry pi 版权所有。 允许以源代码和二进制形式重新分发和使用 前提是上述版权声明和本段 以所有此类形式复制,且任何文件, 广告材料,以及与此相关的其他材料 分发和使用确认软件已开发 由linux-projects.org发布。名称 linux-projects.or,raspberry-pi,webrtc,uv4l,Raspberry Pi,Webrtc,Uv4l,版权所有。 允许以源代码和二进制形式重新分发和使用 前提是上述版权声明和本段 以所有此类形式复制,且任何文件, 广告材料,以及与此相关的其他材料 分发和使用确认软件已开发 由linux-projects.org发布。名称 linux-projects.org不得用于认可或推广衍生产品 未经事先书面许可,不得使用本软件。 本软件按“原样”提供,无任何明示或暗示 默示保证,包括但不限于 对适销性和特定用途适用性的保证。 */ /* *这是一个简单的echo服务器。 *它创建一个unix域套接字,其类

版权所有。 允许以源代码和二进制形式重新分发和使用 前提是上述版权声明和本段 以所有此类形式复制,且任何文件, 广告材料,以及与此相关的其他材料 分发和使用确认软件已开发 由linux-projects.org发布。名称 linux-projects.org不得用于认可或推广衍生产品 未经事先书面许可,不得使用本软件。 本软件按“原样”提供,无任何明示或暗示 默示保证,包括但不限于 对适销性和特定用途适用性的保证。 */ /* *这是一个简单的echo服务器。 *它创建一个unix域套接字,其类型为socku SEQPACKET,由指定 *命令行,侦听它,等待来自客户端的传入消息 *(如UV4L)并将收到的邮件回复给发件人。 * *例如: *$./datachannel_服务器/tmp/uv4l.socket * *要编译此程序,您需要boost v1.60或更高版本,例如: *g++-Wall-I/path/to/boost/include/-std=c++11数据通道_服务器.cpp-L/path/to/boost/lib-L:libboost_协同程序.a-L:libboost_上下文.a-L:libboost_系统.a-L:libboost_线程.a-pthread-o数据通道_服务器 */ #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #包括 #如果!已定义(BOOST\u ASIO\u具有\u本地\u插槽) #错误本地套接字在此平台上不可用。 #恩迪夫 constexpr std::size\u t MAX\u PACKET\u size=1024*16; 命名空间数据包{ 结构seqpacket\u协议{ int type()常量{ 返回SOCK_SEQPACKET; } int协议()常量{ 返回0; } int family()常量{ 返回AF_UNIX; } 使用endpoint=boost::asio::local::basic\u端点; 使用socket=boost::asio::generic::seq_packet_protocol::socket; 使用acceptor=boost::asio::basic\u socket\u acceptor; #如果!已定义(BOOST\u ASIO\u NO\u IOSTREAM) ///UNIX域iostream类型。 使用iostream=boost::asio::basic\u socket\u iostream; #恩迪夫 }; } 使用seqpacket::seqpacket_协议; 结构会话:public std::从\u中启用\u共享\u{ 显式会话(seqpacket_协议::socket socket):socket(std::move(socket)){ ~session(){
//虽然此链接可以回答问题,但最好在此处包含答案的基本部分,并提供链接供参考。如果链接页面发生更改,仅链接的答案可能无效。它不是“仅链接”答案。除非你有更好的答案,否则这是基本部分的答案,并带有官方示例的链接,这也在OP quesiton中引用。不过,你应该在这里添加代码摘录来说明你的答案。谢谢@adminkiam!这正是我需要的。我在测试数据通道时看到了这段代码,但是因为我不想处理C++,我只是把它翻译了一下,我只需要把一些部分翻译成Python,现在它就可以工作了。P@trixr4kdz很高兴知道你已经开始工作了……如果你能用python发布相关的代码,这对其他人会很有帮助
import socket
import time
import pigpio

socket_path = '/tmp/uv4l.socket'

try:
    os.unlink(socket_path)
except OSError:
    if os.path.exists(socket_path):
        raise

s = socket.socket(socket.AF_UNIX, socket.SOCK_SEQPACKET)

ROLL_PIN     = 13
PITCH_PIN    = 14
YAW_PIN      = 15

MIN_PW = 1000
MID_PW = 1500
MAX_PW = 2000

NONE        = 0
LEFT_ARROW  = 1
RIGHT_ARROW = 2
UP_ARROW    = 3
DOWN_ARROW  = 4
LESS_BTN    = 5
GREATER_BTN = 6

print 'socket_path: %s' % socket_path
s.bind(socket_path)
s.listen(1)

def getch(keyCode):
    key = NONE
    if keyCode == 188:
        key = LESS_BTN
    elif keyCode == 190:
        key = GREATER_BTN
    elif keyCode == 37:
        key = LEFT_ARROW
    elif keyCode == 39:
        key = RIGHT_ARROW
    elif keyCode == 38:
        key = UP_ARROW
    elif keyCode == 40:
        key = DOWN_ARROW
    return key

def cleanup():
    pi.set_servo_pulsewidth(ROLL_PIN, 0)
    pi.set_servo_pulsewidth(PITCH_PIN, 0)
    pi.set_servo_pulsewidth(YAW_PIN, 0)
    pi.stop()

while True:
    print 'awaiting connection...'
    connection, client_address = s.accept()
    print 'client_address %s' % client_address
    try:
        print 'established connection with', client_address

        pi = pigpio.pi()

        rollPulsewidth     = MID_PW
        pitchPulsewidth    = MID_PW
        yawPulsewidth      = MID_PW

        pi.set_servo_pulsewidth(ROLL_PIN, rollPulsewidth)
        pi.set_servo_pulsewidth(PITCH_PIN, pitchPulsewidth)
        pi.set_servo_pulsewidth(YAW_PIN, yawPulsewidth)

        while True:
            data = connection.recv(16)
            print 'received message"%s"' % data

            time.sleep(0.01)
            key = getch(int(data))

            rollPW     = rollPulsewidth
            pitchPW    = pitchPulsewidth
            yawPW      = yawPulsewidth

            if key == UP_ARROW:
                pitchPW = pitchPW + 10
                if pitchPW > MAX_PW:
                    pitchPW = MAX_PW
            elif key == DOWN_ARROW:
                pitchPW = pitchPW - 10
                if pitchPW < MIN_PW:
                    pitchPW = MIN_PW
            elif key == LEFT_ARROW:
                rollPW = rollPW - 10
                if rollPW < MIN_PW:
                    rollPW = MIN_PW
            elif key == RIGHT_ARROW:
                rollPW = rollPW + 10
                if rollPW > MAX_PW:
                    rollPW = MAX_PW
            elif key == GREATER_BTN:
                yawPW = yawPW + 10
                if yawPW > MAX_PW:
                    yawPW = MAX_PW
            elif key == LESS_BTN:
                yawPW = yawPW - 10
                if yawPW < MIN_PW:
                    yawPW = MIN_PW

            if rollPW != rollPulsewidth:
                rollPulsewidth = rollPW
                pi.set_servo_pulsewidth(ROLL_PIN, rollPulsewidth)
            if pitchPW != pitchPulsewidth:
                pitchPulsewidth = pitchPW
                pi.set_servo_pulsewidth(PITCH_PIN, pitchPulsewidth)
            if yawPW != yawPulsewidth:
                yawPulsewidth = yawPW
                pi.set_servo_pulsewidth(YAW_PIN, yawPulsewidth)

            if data:
                print 'echo data to client'
                connection.sendall(data)
            else:
                print 'no more data from', client_address
                break

    finally:
        # Clean up the connection
        cleanup()
        connection.close()
/*
    Copyright (c) 2016 info@linux-projects.org
    All rights reserved.

    Redistribution and use in source and binary forms are permitted
    provided that the above copyright notice and this paragraph are
    duplicated in all such forms and that any documentation,
    advertising materials, and other materials related to such
    distribution and use acknowledge that the software was developed
    by the linux-projects.org. The name of the
    linux-projects.org may not be used to endorse or promote products derived
    from this software without specific prior written permission.
    THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
    IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
    WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*/

/*
 * This is a simple echo server.
 * It creates to a unix domain socket of type SOCK_SEQPACKET specified by
 * command line, listens to it waiting for incoming messages from clients
 * (e.g. UV4L) and replies the received messages back to the senders.
 *
 * Example:
 *     $ ./datachannel_server /tmp/uv4l.socket
 *
 * To compile this program you need boost v1.60 or greater, for example:
 * g++ -Wall -I/path/to/boost/include/ -std=c++11 datachannel_server.cpp -L/path/to/boost/lib -l:libboost_coroutine.a -l:libboost_context.a -l:libboost_system.a -l:libboost_thread.a -pthread -o datachannel_server
 */

#include <boost/asio/io_service.hpp>
#include <boost/asio/spawn.hpp>
#include <boost/asio/write.hpp>
#include <boost/asio/buffer.hpp>
#include <boost/asio.hpp>
#include <memory>
#include <cstdio>
#include <array>
#include <functional>
#include <iostream>

#if !defined(BOOST_ASIO_HAS_LOCAL_SOCKETS)
#error Local sockets not available on this platform.
#endif

constexpr std::size_t MAX_PACKET_SIZE = 1024 * 16;

namespace seqpacket {

    struct seqpacket_protocol {

        int type() const {
            return SOCK_SEQPACKET;
        }

        int protocol() const {
            return 0;
        }

        int family() const {
            return AF_UNIX;
        }

        using endpoint = boost::asio::local::basic_endpoint<seqpacket_protocol>;
        using socket = boost::asio::generic::seq_packet_protocol::socket;
        using acceptor = boost::asio::basic_socket_acceptor<seqpacket_protocol>;

#if !defined(BOOST_ASIO_NO_IOSTREAM)
        /// The UNIX domain iostream type.
        using iostream = boost::asio::basic_socket_iostream<seqpacket_protocol>;
#endif
    };
}

using seqpacket::seqpacket_protocol;

struct session : public std::enable_shared_from_this<session> {
    explicit session(seqpacket_protocol::socket socket) : socket_(std::move(socket)) {}

    ~session() {
        //std::cerr << "session closed\n";
    }

    void echo(boost::asio::yield_context yield) {
        auto self = shared_from_this();
        try {
            for (;;) {
                seqpacket_protocol::socket::message_flags in_flags = MSG_WAITALL, out_flags = MSG_WAITALL;

                // Wait for the message from the client
                auto bytes_transferred = socket_.async_receive(boost::asio::buffer(data_), in_flags, yield);

                // Write the same message back to the client
                socket_.async_send(boost::asio::buffer(data_, bytes_transferred), out_flags, yield);
            }
        } catch (const std::exception& e) {
            std::cerr << e.what() << '\n';
            socket_.close();
        }
    }

    void go() {
        boost::asio::spawn(socket_.get_io_service(), std::bind(&session::echo, this, std::placeholders::_1));
    }

private:
    seqpacket_protocol::socket socket_;
    std::array<char, MAX_PACKET_SIZE> data_;
};

int main(int argc, char* argv[]) {
    try {
        if (argc != 2) {
            std::cerr << "Usage: datachannel_server <file> (e.g. /tmp/uv4l.socket)\n";
            std::cerr << "*** WARNING: existing file is removed ***\n";
            return EXIT_FAILURE;
        }

        boost::asio::io_service io_service;

        std::remove(argv[1]);

        boost::asio::spawn(io_service, [&](boost::asio::yield_context yield) {
                    seqpacket_protocol::acceptor acceptor_(io_service, seqpacket_protocol::endpoint(argv[1]));
                    for (;;) {
                        boost::system::error_code ec;
                        seqpacket_protocol::socket socket_(io_service);
                        acceptor_.async_accept(socket_, yield[ec]);
                        if (!ec)
                            std::make_shared<session>(std::move(socket_))->go();
                    }
                });

        io_service.run();

    } catch (std::exception& e) {
        std::cerr << "Exception: " << e.what() << "\n";
        return EXIT_FAILURE;
    }
}