iOS Swift: как проверить, открыт ли порт

В моем приложении хочу проверить, открыт порт или нет. Вот ссылка на эту ссылку

SDK для iOS: как проверить наличие порта открыто?

Но у меня нет никакого решения. А также укажите эти два источника на github,

https://github.com/swiftsocket/SwiftSocket

https://github.com/robbiehanson/CocoaAsyncSocket

Но нет никакого решения. Любая помощь, как проверить, открыт порт или нет. Спасибо заранее.


person saravanar    schedule 16.05.2019    source источник


Ответы (2)


Используйте описанный ниже метод, чтобы порт открыт или нет

func isPortOpen(port: in_port_t) -> Bool {

    let socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0)
    if socketFileDescriptor == -1 {
        return false
    }

    var addr = sockaddr_in()
    let sizeOfSockkAddr = MemoryLayout<sockaddr_in>.size
    addr.sin_len = __uint8_t(sizeOfSockkAddr)
    addr.sin_family = sa_family_t(AF_INET)
    addr.sin_port = Int(OSHostByteOrder()) == OSLittleEndian ? _OSSwapInt16(port) : port
    addr.sin_addr = in_addr(s_addr: inet_addr("0.0.0.0"))
    addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0)
    var bind_addr = sockaddr()
    memcpy(&bind_addr, &addr, Int(sizeOfSockkAddr))

    if Darwin.bind(socketFileDescriptor, &bind_addr, socklen_t(sizeOfSockkAddr)) == -1 {
        return false
    }
    if listen(socketFileDescriptor, SOMAXCONN ) == -1 {
        return false
    }
    return true
}

Используйте как:

let port = UInt16(10000)
print(isPortOpen(port:port))
person Hitesh Surani    schedule 16.05.2019
comment
addr.sin_addr = in_addr (s_addr: inet_addr (0.0.0.0)) и addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0) в этих двух строках для 0, что я хочу добавить? Помоги мне? - person saravanar; 16.05.2019
comment
Просто замените 0.0.0.0 URL-адресом вашего сокета, например 127.0.0.1 для localhost, остальное оставьте как есть - person Hitesh Surani; 16.05.2019
comment
addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0) в этой строке, что я должен добавить для 0? - person saravanar; 20.05.2019
comment
как получить URL-адрес сокета, помогите мне? - person saravanar; 20.05.2019
comment
ты можешь ответить на мой вопрос? - person saravanar; 21.05.2019
comment
Этот ответ оставляет каждый проверяемый порт в открытом состоянии и прослушивает его, что, вероятно, не то, что вам нужно. Другой ответ показывает, как закрыть порт после проверки. - person neuralmer; 13.03.2021

Я не могу добавлять комментарии, поэтому добавляю это как отдельный ответ. Я последовал ответу Сурани, но обнаружил ошибки при использовании порта позже в приложении. Я обнаружил, что мне нужно вручную закрыть сокет, прежде чем возвращать ответ.

Поэтому я изменил последние 4 строки на

    let isOpen = listen(socketFileDescriptor, SOMAXCONN ) != -1
    Darwin.close(socketFileDescriptor)
    return isOpen

Вот исправленная версия ответа Сурани с кодом закрытия сокета

func isPortOpen(port: in_port_t) -> Bool {

    let socketFileDescriptor = socket(AF_INET, SOCK_STREAM, 0)
    if socketFileDescriptor == -1 {
        return false
    }

    var addr = sockaddr_in()
    let sizeOfSockkAddr = MemoryLayout<sockaddr_in>.size
    addr.sin_len = __uint8_t(sizeOfSockkAddr)
    addr.sin_family = sa_family_t(AF_INET)
    addr.sin_port = Int(OSHostByteOrder()) == OSLittleEndian ? _OSSwapInt16(port) : port
    addr.sin_addr = in_addr(s_addr: inet_addr("0.0.0.0"))
    addr.sin_zero = (0, 0, 0, 0, 0, 0, 0, 0)
    var bind_addr = sockaddr()
    memcpy(&bind_addr, &addr, Int(sizeOfSockkAddr))

    if Darwin.bind(socketFileDescriptor, &bind_addr, socklen_t(sizeOfSockkAddr)) == -1 {
        return false
    }
    let isOpen = listen(socketFileDescriptor, SOMAXCONN ) != -1
    Darwin.close(socketFileDescriptor)
    return isOpen
}

Используйте как:

let port = UInt16(10000)
print(isPortOpen(port:port))
person bedalton    schedule 05.12.2020
comment
Спасибо, это помогло освободить порт после проверки. - person Heestand XYZ; 23.01.2021