Swift 将[UInt8]数组转换为xinpgen结构

Swift 将[UInt8]数组转换为xinpgen结构,swift,memory,struct,memory-layout,Swift,Memory,Struct,Memory Layout,我有以下代码来获取有关tcp端口的信息: var length = 0 if (sysctlbyname("net.inet.tcp.pcblist", nil, &length, nil, 0) < 0) { perror("sysctlbyname") } else { var buffer: [UInt8] = [UInt8](repeating: 0, count: Int(length)) sysctlbyname("net.inet.tcp.pc

我有以下代码来获取有关tcp端口的信息:

var length = 0
if (sysctlbyname("net.inet.tcp.pcblist", nil, &length, nil, 0) < 0)
{
    perror("sysctlbyname")
}
else
{
    var buffer: [UInt8] = [UInt8](repeating: 0, count: Int(length))
    sysctlbyname("net.inet.tcp.pcblist", &buffer, &length, nil, 0)
}

如何使用缓冲区填充struct变量?为什么第二次调用失败?

sysctlbyname(“net.inet.tcp.pcblist”…)返回的数据 不是单一的
xinpgen
结构,而是 结构

您的代码将更多字节写入
输入的内存地址
变量大于其大小,行为未定义,碰撞非常严重 很可能

我不知道返回数据的结构是否有文档记录,但是 的源代码显示了如何解析它。 显然,缓冲区以结构xinpgen开始,后面是 通过变量数量的
struct xtcpcb
,每个元素都有 包含到下一个结构的偏移量的长度字段

这是我试图翻译上述源代码中的C代码 向Swift提交文件:

var length = 0
if (sysctlbyname("net.inet.tcp.pcblist", nil, &length, nil, 0) < 0) {
    fatalError("sysctlbyname")
}

var buffer = [UInt8](repeating: 0, count: Int(length))
sysctlbyname("net.inet.tcp.pcblist", &buffer, &length, nil, 0)

buffer.withUnsafeBytes { bufPtr in

    // Pointer to first xinpgen structure:
    var p = bufPtr.baseAddress!
    var xig = p.bindMemory(to: xinpgen.self, capacity: 1)

    // Skip first xinpgen structure:
    p += Int(xig.pointee.xig_len)
    xig = p.bindMemory(to: xinpgen.self, capacity: 1)

    while Int(xig.pointee.xig_len) > MemoryLayout<xinpgen>.size {
        // Cast xig to xtcpcb pointer and derefernce:
        let tcpcb = xig.withMemoryRebound(to: xtcpcb.self, capacity: 1) {
            $0.pointee
        }
        print(tcpcb)

        // Advance pointer to next structure
        p += Int(xig.pointee.xig_len)
        xig = p.bindMemory(to: xinpgen.self, capacity: 1)
    }
}
var长度=0
if(sysctlbyname(“net.inet.tcp.pcblist”,nil,&length,nil,0)<0){
fatalError(“sysctlbyname”)
}
变量缓冲区=[UInt8](重复:0,计数:Int(长度))
sysctlbyname(“net.inet.tcp.pcblist”,&buffer,&length,nil,0)
buffer.withUnsafeBytes{bufPtr in
//指向第一个xinpgen结构的指针:
var p=bufPtr.baseAddress!
var xig=p.bindMemory(收件人:xinpgen.self,容量:1)
//跳过第一个xinpgen结构:
p+=Int(xig.pointee.xig_len)
xig=p.bindMemory(收件人:xinpgen.self,容量:1)
而Int(xig.pointee.xig_len)>MemoryLayout.size{
//将xig转换为xtcpcb指针和解除引用:
让tcpcb=xig.withMemoryRebound(to:xtcpcb.self,容量:1){
0.1元
}
打印(tcpcb)
//前进指针到下一个结构
p+=Int(xig.pointee.xig_len)
xig=p.bindMemory(收件人:xinpgen.self,容量:1)
}
}

这显然不是C代码。它是Swift,但我想将“Swift对象”转换为C结构。“我想将“Swift对象”转换为C结构”-不完全是这样。您希望将swift对象转换为与平台的C ABI兼容的内存块。这与C语言无关,但这是一个纯粹的swift问题。谢谢,我成功了。netstat打印url(stackoverflow.com或localhost)而不是IP地址。有没有办法通过Swift获得这些信息?我有IP地址并需要url。@SaschaSimon:
getnameinfo()
可以用来获取IP地址的主机名。@SaschaSimon:这可能会有帮助(但没有NI_数字…选项)@SaschaSimon:如果你有一个in_addr,那么你只需填写sa_addr,SaschaSimon:getnameinfo用于IPv4+6地址。它获取指向sockaddr的指针作为参数,该指针可以指向sockaddr_in6(或可容纳各种地址的sockaddr_存储器)。-我无法回答您的其他问题,但请注意,“lsof”是开源的,您可以检查它的功能。
error: memory read failed for 0x0
var length = 0
if (sysctlbyname("net.inet.tcp.pcblist", nil, &length, nil, 0) < 0) {
    fatalError("sysctlbyname")
}

var buffer = [UInt8](repeating: 0, count: Int(length))
sysctlbyname("net.inet.tcp.pcblist", &buffer, &length, nil, 0)

buffer.withUnsafeBytes { bufPtr in

    // Pointer to first xinpgen structure:
    var p = bufPtr.baseAddress!
    var xig = p.bindMemory(to: xinpgen.self, capacity: 1)

    // Skip first xinpgen structure:
    p += Int(xig.pointee.xig_len)
    xig = p.bindMemory(to: xinpgen.self, capacity: 1)

    while Int(xig.pointee.xig_len) > MemoryLayout<xinpgen>.size {
        // Cast xig to xtcpcb pointer and derefernce:
        let tcpcb = xig.withMemoryRebound(to: xtcpcb.self, capacity: 1) {
            $0.pointee
        }
        print(tcpcb)

        // Advance pointer to next structure
        p += Int(xig.pointee.xig_len)
        xig = p.bindMemory(to: xinpgen.self, capacity: 1)
    }
}