Home > database >  How to get sockaddr from sockaddr_in in Swift?
How to get sockaddr from sockaddr_in in Swift?

Time:10-27

Hi this is the objective code I've that sending broadcast message successfully,

- (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); 
    }

I tried convert this code to swift but I don't know How to convert sockaddr_in into sockaddr. Here is the swift code I been tried,

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)
    }

Please help me. Thank you.

CodePudding user response:

I translated the code based on your start as:

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)")
    }
}

If I run it, it doesn't crash and returns a positive result, but I don't know that it works properly.

  • Related