python学习之socket应用

环境说明

本文的代码运行环境:
windows 10,python 3.7(代码兼容python 2)

实现的目标:
1、实现nslookup 命令,查询域名对应的ip地址
2、实现ping命令,查询目标ip是否在线

代码实现

nslookup命令实现

import socket
import sys


def nslookup(domain):
    result = socket.getaddrinfo(domain,53,socket.AF_INET,socket.SOCK_DGRAM,17,0)
    #print(result)
    num=len(result)
    #print(num)
    for a in range(num):
        i = result[a][4][0]
        print(i)


if __name__ == '__main__':
    try:
        domain = sys.argv[1]
    except:
        print('Usage: %s www.baidu.com' % sys.argv[0])
        exit()
    nslookup(domain)

ping命令实现(icmp协议数据包模拟

# coding=utf-8
import os
import sys
import socket
import struct
import select

try:
    from time import perf_counter
except:
    from time import clock as perf_counter

ICMP_ECHO_REQUEST = 8

def receive_ping(my_socket, ID, timeout):
    """
    receive the ping from the socket
    """
    start_time = timeout
    while True:
        start_select = perf_counter()
        # select.select(rlist, wlist, xlist[, timeout])
        # wait until ready for read / write / exceptional condition
        # The return value is a triple of lists
        what_ready = select.select([my_socket], [], [], start_time)
        how_long = perf_counter() - start_select
        if what_ready[0] == []: #timeout
            return None
        time_received = perf_counter()
        # socket.recvfrom(bufsize[, flags])
        # The return value is a pair (string, address)
        rec_packet, addr = my_socket.recvfrom(1024)
        icmp_header = rec_packet[20:28]
        ip_type, code, checksum, packet_ID, sequence = struct.unpack("bbHHh", icmp_header)
        if ip_type != 8 and packet_ID == ID: # ip_type should be 0
            byte_in_double = struct.calcsize("d")
            time_sent = struct.unpack("d", rec_packet[28:28 + byte_in_double])[0]
            return time_received - time_sent
        start_time = start_time - how_long
        if start_time <= 0:
            return None


def get_checksum(source):
    """
    return the checksum of source
    the sum of 16-bit binary one's complement
    """
    #print(type(source)) # in py2, str; in py3, bytes
    checksum = 0
    count = int((len(source) // 2) * 2)
    i = 0
    while i < count:
        if sys.version.startswith('3.'):
            temp = source[i + 1] * 256 + source[i] # 256 = 2^8
        else:
            temp = ord(source[i + 1]) * 256 + ord(source[i]) # 256 = 2^8
        checksum += temp
        checksum = checksum & 0xffffffff # 4,294,967,296 (2^32)
        i = i + 2
    if i < len(source):
        if sys.version.startswith('3.'):
            checksum += source[len(source) - 1]
        else:
            checksum += ord(source[len(source) - 1])
        checksum = checksum & 0xffffffff
    # 32-bit to 16-bit
    checksum = (checksum >> 16) + (checksum & 0xffff)
    checksum = checksum + (checksum >> 16)
    answer = ~checksum
    answer = answer & 0xffff
    # why? ans[9:16 1:8]
    answer = answer >> 8 | (answer << 8 & 0xff00)
    return answer



def send_ping(my_socket, ip_addr, ID):
    """
    send ping to the given ip address
    """
    ip = socket.gethostbyname(ip_addr)
    # Header is type (8), code (8), checksum (16), id (16), sequence (16)
    my_checksum = 0
    # Make a dummy heder with a 0 checksum
    # b:signed char, h:short 2, H:unsigned short 2
    header = struct.pack('bbHHh', ICMP_ECHO_REQUEST, 0, my_checksum, ID, 1)
    # struct.calcsize(fmt)
    # Return the size of the struct corresponding to the given format.
    byte_in_double = struct.calcsize("d") # C type: double, 8
    data = (192 - byte_in_double) * b"P" # any char is OK, any length is OK
    tt = perf_counter()
    data = struct.pack("d", tt) + data
    my_checksum = get_checksum(header + data)
    header = struct.pack("bbHHh", ICMP_ECHO_REQUEST, 0, socket.htons(my_checksum), ID, 1)
    packet = header + data
    my_socket.sendto(packet, (ip, 80)) # it seems that 0~65535 is OK (port?)


def ping_once(ip_addr, timeout):
    """
    return either delay (in second) or none on timeout.
    """
    icmp = socket.getprotobyname('icmp')
    try:
        my_socket = socket.socket(socket.AF_INET, socket.SOCK_RAW, icmp)
    except socket.error:
        raise
    # Return the current process id.
    # int: 0xFFFF = -1, unsigned int: 65535
    my_ID = os.getpid() & 0xFFFF
    send_ping(my_socket, ip_addr, my_ID)
    delay = receive_ping(my_socket, my_ID, timeout)
    my_socket.close()
    return delay


def icmp_ping(ip_addr, timeout = 2, count = 1):
    """
    send ping to ip_addr for count times with the given timeout
    """
    for i in range(count):
        print('ping ' + ip_addr)
        try:
            delay = ping_once(ip_addr, timeout)
        except socket.gaierror as e:
            print("failed. (socket error: '%s')" % e[1])
            break
        if delay == None:
            print('failed. (timeout within %s second.)' % timeout)
        else:
            print('get reply in %0.4f ms' % (delay * 1000))



if __name__ == '__main__':
    try:
        ip_addr = sys.argv[1]
    except:
        print('Usage: %s 1.2.3.4' % sys.argv[0])
        exit()
    icmp_ping(ip_addr)

参考文献:
ICMP协议Ping方法的Python实现解析

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Python是一种简单易学且功能强大的编程语言,而ABB Socket是ABB公司开发的一种用于实时通信的软件组件。下面我将分别介绍一下两者的主要特点和用途。 Python是一种高级编程语言,具有清晰简洁的语法结构和丰富的标准库,可以满足各种编程需求。它被广泛应用于数据分析、人工智能、网络开发、自动化测试等领域。Python还有一个庞大的第三方库生态系统,提供了众多的功能模块,可以快速开发各种应用程序。 ABB Socket是ABB公司为其自动化设备开发的用于实时通信的软件组件。它基于Socket编程技术,可以在ABB设备与其他设备之间建立可靠的通信连接。ABB Socket支持多种通信协议,如TCP/IP、UDP等,同时还提供了丰富的API接口,方便开发人员进行二次开发和集成。 Python与ABB Socket可以结合使用,在工业自动化领域中起到非常重要的作用。通过Python的优势,可以方便快捷地开发各种自动化控制系统、监控系统以及数据采集系统等,并且可以方便地与ABB Socket进行通信,实现设备间的数据传输和控制指令的发送与接收。 总结来说,Python是一种强大的编程语言,而ABB Socket是ABB公司为实时通信开发的软件组件。两者结合使用,可以在工业自动化领域中实现各种功能,提高生产效率和控制精度。 ### 回答2: Python是一种通用的高级编程语言,而ABB Socket是ABB机器人控制器中用于与外部设备通信的一种通信插件。 Python是一门易于学习和使用的编程语言,拥有简洁的语法和丰富的库,使得开发者可以快速地开发各种应用Python具有跨平台的特性,可以在不同的操作系统上运行。 与之相比,ABB Socket是ABB机器人控制器的一部分,用于与外部设备进行通信。它使机器人能够与其他设备进行数据交换和控制指令的传递。ABB Socket支持多种通信协议,如TCP/IP、UDP等,并且提供了一套丰富的API,供开发者使用。 Python和ABB Socket之间可以进行结合使用。通过PythonSocket库,我们可以在Python程序中创建Socket连接,从而实现与ABB Socket的通信。这样,我们就可以在Python程序中发送指令给机器人,或者从机器人读取传感器数据。 利用Python和ABB Socket,我们可以编写各种应用,如机器人远程监控,机器人与其他设备的协同工作等。例如,我们可以编写一个基于Python和ABB Socket的程序,监控机器人的状态,并实时向操作者反馈机器人的位置、速度和执行任务的进度等信息。 总而言之,Python和ABB Socket在不同的领域具有各自的优势,结合使用可以实现更多的功能和应用。无论是学习编程还是进行机器人控制,了解和掌握这两方面的知识都是非常有用的。 ### 回答3: Python是一种开源的高级编程语言,而ABB Socket是ABB机器人的通信接口。 Python是一种功能强大且易于学习的编程语言,它具有简洁的语法和丰富的第三方库,使得编写代码变得更加便捷和高效。Python可用于开发各种类型的应用程序,包括Web应用、数据分析、机器学习、人工智能等。它的跨平台性使得Python在不同操作系统上都能运行,同时它还支持面向对象编程、函数式编程和模块化编程等多种编程范式。 ABB Socket是ABB机器人提供的一种通信接口,它允许开发人员通过网络与ABB机器人进行通信和远程控制。通过ABB Socket,我们可以发送和接收数据,并且可以实现远程控制机器人的运动和操作。这种通信方式非常灵活,可以使用多种编程语言进行开发,包括Python。使用Python编写的程序可以通过ABB Socket与ABB机器人进行通信,从而实现自动化的机器人操作和控制。 Python和ABB Socket的结合为我们提供了便捷的机器人编程和控制方式。通过Python的简洁语法和丰富的库函数,我们可以轻松地编写代码来实现与ABB机器人的交互和控制。同时,使用ABB Socket作为通信接口,我们可以实现实时的数据传输和命令执行,从而实现更加精确和高效的机器人控制。 总而言之,Python和ABB Socket相结合为我们提供了一种快速、灵活和高效的方式来编程和控制ABB机器人。无论是在工业自动化还是科研领域,这种组合都具有广泛的应用前景。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值