D编程语言中的UDP套接字

Jer*_*emy 2 python sockets udp d

我正在尝试将python程序转换为D; 该程序用于发送Art-Net DMX数据包.

蟒蛇:

import sys, socket, math, time
from ctypes import *

class ArtNetDMXOut(LittleEndianStructure):
    PORT = 0x1936
    _fields_ = [("id", c_char * 8),
                ("opcode", c_ushort),
                ("protverh", c_ubyte),
                ("protver", c_ubyte),
                ("sequence", c_ubyte),
                ("physical", c_ubyte),         
                ("universe", c_ushort),
                ("lengthhi", c_ubyte),
                ("length", c_ubyte),
                ("payload", c_ubyte * 512)]
    def __init__(self):
        self.id = b"Art-Net"
        self.opcode = 0x5000
        self.protver = 14
        self.universe = 0
        self.lengthhi = 2

def main():
    hostIP = "localhost"
    S = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
    packet = ArtNetDMXOut()

    packet.payload[0] = 255
    S.sendto(packet, (hostIP, ArtNetDMXOut.PORT))

if __name__ == "__main__":
    main()
Run Code Online (Sandbox Code Playgroud)

d:

import std.stdio;
import std.socket;

class ArtNetDMX{
    char id[8];
    ushort opCode;
    ubyte verH;
    ubyte ver;
    ubyte sequence;
    ubyte physical;
    ushort universe;
    ubyte lengthHi;
    ubyte length;
    ubyte data[511];

    this(){
        this.id = "ART-NET0";
        this.opCode = 0x5000;
        this.ver = 14;
        this.universe = 0;
        this.lengthHi = 2;
    }

}

void main() {
    auto s = new UdpSocket();
    auto addr = new InternetAddress("localhost", 6454);
    s.bind(addr);
    ArtNetDMX packet = new ArtNetDMX();

    packet.data[0] = 255;

    s.send(packet);
};
Run Code Online (Sandbox Code Playgroud)

我的Python代码的工作原理完全如预期,但在DI得到错误function std.socket.Socket.send (const(void)[] buf, SocketFlags flags) is not callable using argument types (ArtNetDMX)s.send(packet);路线.

我接近这个吗?我究竟做错了什么?

bee*_*boy 5

首先,你需要ArtNetDMX成为一个struct,而不是class- 因为D中的类是引用类型,并且不保证类字段布局; 并且由于您通过电线发送它,请指定适当的对齐方式(如果要将每个字段打包在一起,通常为1):

struct ArtNetDMX {
    align(1):
    ....
}
Run Code Online (Sandbox Code Playgroud)

在您的中main,您现在可以在堆栈上分配它的实例:

ArtNetDMX packet;        // no `new` required

packet.id = "ART-NET0";  // initialize fields
packet.opCode = 0x5000;
packet.ver = 14;
packet.universe = 0;
packet.lengthHi = 2;
Run Code Online (Sandbox Code Playgroud)

或者,如果您经常执行相同的初始化,请将其移动到一个函数中:

ArtNetDMX createArtNetDMX()
{
    ArtNetDMX packet;

    packet.id = "ART-NET0";
    packet.opCode = 0x5000;
    packet.ver = 14;
    packet.universe = 0;
    packet.lengthHi = 2;

    return packet;
}
Run Code Online (Sandbox Code Playgroud)

最后,Socket.send要求其参数为切片(数组或部分).如果您最终一次发送多个数据包,则将数据包放入数组,然后发送数组.

由于您只发送一个数据包,因此可以替换

s.send(packet);
Run Code Online (Sandbox Code Playgroud)

s.send((&packet)[0..1]);
Run Code Online (Sandbox Code Playgroud)

这只是将对象转换为1元素切片的安全方法.