如何在 Swift 中从 sockaddr_in 获取 sockaddr?
Posted
技术标签:
【中文标题】如何在 Swift 中从 sockaddr_in 获取 sockaddr?【英文标题】:How to get sockaddr from sockaddr_in in Swift? 【发布时间】:2021-12-12 07:31:43 【问题描述】:您好,这是我成功发送广播消息的目标代码,
- (void)send: (NSString *)address
int socketSD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if (socketSD <= 0)
NSLog(@"Error: Could not open socket.");
return;
// set socket options enable broadcast
int broadcastEnable = 1;
int ret = setsockopt(socketSD, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, sizeof(broadcastEnable));
if (ret)
NSLog(@"Error: Could not open set socket to broadcast mode");
close(socketSD);
return;
// Configure the port and ip we want to send to
struct sockaddr_in broadcastAddr;
memset(&broadcastAddr, 0, sizeof(broadcastAddr));
broadcastAddr.sin_family = AF_INET;
const char *broadCast = [address UTF8String];
inet_pton(AF_INET, broadCast, &broadcastAddr.sin_addr);
broadcastAddr.sin_port = htons(2425);
char *request = "message";
ret = sendto(socketSD, request, strlen(request), 0, (struct sockaddr*)&broadcastAddr, sizeof(broadcastAddr));
if (ret < 0)
NSLog(@"Error: Could not open send broadcast.");
close(socketSD);
return;
close(socketSD);
我尝试将此代码转换为 swift,但我不知道如何将 sockaddr_in
转换为 sockaddr
。这是我尝试过的快速代码,
func send(_ address: String)
let socketSD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
if socketSD <= 0
print("Error: Could not open socket.")
return
// set socket options enable broadcast
var broadcastEnable = 1
var ret = setsockopt(socketSD, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, socklen_t(MemoryLayout.size(ofValue: broadcastEnable)))
if ret != 0
print("Error: Could not open set socket to broadcast mode")
close(socketSD)
return
var broadcastAddr: sockaddr_in!
memset(&broadcastAddr, 0, MemoryLayout.size(ofValue: broadcastAddr))
if broadcastAddr == nil
return
broadcastAddr.sin_family = sa_family_t(AF_INET)
let broadCast: UnsafeMutablePointer<Int8>? = address.toUnsafeMutablePointer()
inet_pton(AF_INET, broadCast, &broadcastAddr.sin_addr)
broadcastAddr.sin_port = in_port_t(2425)
let request = ("message" as NSString).utf8String
var unsafePointerAddress: sockaddr = // I am not sure how to get sockaddr from `broadcastAddr`
ret = Int32(
sendto(socketSD, request!, strlen(request!), 0, &unsafePointerAddress, socklen_t(MemoryLayout.size(ofValue: broadcastAddr)))
)
if ret < 0
print("Error: Could not open send broadcast.")
close(socketSD)
return
close(socketSD)
请帮助我。谢谢。
【问题讨论】:
【参考方案1】:我根据您的开头将代码翻译为:
func send(_ address: String)
let socketSD = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP)
guard socketSD > 0 else print("Error: Could not open socket."); return
defer close(socketSD)
// set socket options enable broadcast
var broadcastEnable = 1
let ret = setsockopt(socketSD, SOL_SOCKET, SO_BROADCAST, &broadcastEnable, socklen_t(MemoryLayout.size(ofValue: broadcastEnable)))
guard ret == 0 else print("Error: Could not open set socket to broadcast mode"); return
var broadcastAddr = sockaddr_in(sin_len: 0,
sin_family: sa_family_t(AF_INET),
sin_port: in_port_t(UInt16(1314).bigEndian),
sin_addr: in_addr(s_addr: 0),
sin_zero: (0,0,0,0,0,0,0,0))
let broadcastAddrSize = MemoryLayout.size(ofValue: broadcastAddr)
address.withCString
address in
inet_pton(AF_INET, address, &broadcastAddr.sin_addr)
let result = withUnsafePointer(to: &broadcastAddr)
return $0.withMemoryRebound(to: sockaddr.self, capacity: 1) aSockaddr in
return "message".withCString message in
return sendto(socketSD, message, strlen(message), 0, aSockaddr, socklen_t(broadcastAddrSize))
print(result)
if result < 0
print("Error: Could not open send broadcast. \(result)")
如果我运行它,它不会崩溃并返回肯定的结果,但我不知道它是否正常工作。
【讨论】:
感谢您的回答。但它不起作用。我收到错误Could not open send broadcast. -1
。 nc -luk 1314
是收听广播消息的终端命令。使用ifconfig
可以得到broadcast
的IP地址。
Swift 版本 和 Objective-C 版本都给了我相同的结果 对 sendto
的调用失败并返回 -1 并留下 errno 值为 1 (域错误)。你知道 Objective-C 的愿景是否奏效了吗?
是的,您的解决方案运行良好。问题是我们忘记检查Xcode中App Sandbox
的传出连接Signing and Capabilities.
谢谢你的回答。以上是关于如何在 Swift 中从 sockaddr_in 获取 sockaddr?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Swift 中从 NSDictionary 生成 JSON 数据