Swift 将[UInt8]数组转换为xinpgen结构
我有以下代码来获取有关tcp端口的信息: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
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)
}
}