Python DNS Server IP Address Query - python

I am trying to get the DNS Server IP Addresses using python. To do this in Windows command prompt, I would use
ipconfig -all
As shown below:
I want to do the exact same thing using a python script. Is there any way to extract these values?
I was successful in extracting the IP address of my device, but DNS Server IP is proving to be more challenging.

I recently had to get the IP addresses of the DNS servers that a set of cross platform hosts were using (linux, macOS, windows), this is how I ended up doing it and I hope it's helpful:
#!/usr/bin/env python
import platform
import socket
import subprocess
def is_valid_ipv4_address(address):
try:
socket.inet_pton(socket.AF_INET, address)
except AttributeError: # no inet_pton here, sorry
try:
socket.inet_aton(address)
except socket.error:
return False
return address.count('.') == 3
except socket.error: # not a valid address
return False
return True
def get_unix_dns_ips():
dns_ips = []
with open('/etc/resolv.conf') as fp:
for cnt, line in enumerate(fp):
columns = line.split()
if columns[0] == 'nameserver':
ip = columns[1:][0]
if is_valid_ipv4_address(ip):
dns_ips.append(ip)
return dns_ips
def get_windows_dns_ips():
output = subprocess.check_output(["ipconfig", "-all"])
ipconfig_all_list = output.split('\n')
dns_ips = []
for i in range(0, len(ipconfig_all_list)):
if "DNS Servers" in ipconfig_all_list[i]:
# get the first dns server ip
first_ip = ipconfig_all_list[i].split(":")[1].strip()
if not is_valid_ipv4_address(first_ip):
continue
dns_ips.append(first_ip)
# get all other dns server ips if they exist
k = i+1
while k < len(ipconfig_all_list) and ":" not in ipconfig_all_list[k]:
ip = ipconfig_all_list[k].strip()
if is_valid_ipv4_address(ip):
dns_ips.append(ip)
k += 1
# at this point we're done
break
return dns_ips
def main():
dns_ips = []
if platform.system() == 'Windows':
dns_ips = get_windows_dns_ips()
elif platform.system() == 'Darwin':
dns_ips = get_unix_dns_ips()
elif platform.system() == 'Linux':
dns_ips = get_unix_dns_ips()
else:
print("unsupported platform: {0}".format(platform.system()))
print(dns_ips)
return
if __name__ == "__main__":
main()
Resources I used to make this script:
https://stackoverflow.com/a/1325603
https://stackoverflow.com/a/4017219
Edit: If anyone has a better way of doing this please share :)

DNS Python (dnspython) might be helpful. You can get the DNS server address with:
import dns.resolver
dns_resolver = dns.resolver.Resolver()
dns_resolver.nameservers[0]

Related

Need help creating a mac filter because I am stuck making a while loop

Alright so for a school assignment me and my classmate decided to make a macfiler/ids script in python3. We got pretty far but we are stuck at 1 thing. We need the scan to go on infinite and break when a new connection in the network is found and continue when the new connection is blocked or not. Could someone help us in the right direction?
from scapy.all import ARP, Ether, srp
import os
import netifaces
#Ask for the subnet mask and calculate it to CIDR notation
netmask = input("What is the subnetmask of your network? (xxx.xxx.xxx.xxx:)")
CIDR = sum(bin(int(x)).count('1') for x in netmask.split('.'))
#Find the defaultgateway ip
gateways = netifaces.gateways()
default_gateway = gateways['default'][netifaces.AF_INET][0]
#Conversions to make the code easier to read
target_ip = default_gateway + "/" + str(CIDR)
arp = ARP(pdst=target_ip)
ether = Ether(dst="ff:ff:ff:ff:ff:ff")
packet = ether/arp
result = srp(packet, timeout=3, verbose=0)[0]
#Empty list for the found clients in the network
clients = []
#Empty list for the blocked addresses
blockedMac = []
#This needs an infinite loop and break when a new connection is in the network is found
for sent, received in result:
clients.append({'ip': received.psrc, 'mac': received.hwsrc})
#if new connection is found do this
print("Available devices in the network:\n")
print("IP" + " "*18+"MAC")
for client in clients:
print("{:16} {}".format(client['ip'], client['mac']))
blockedConnectionStatus = input("\nWould you like to block a connection? Y/n:")
if blockedConnectionStatus == 'Y' or blockedConnectionStatus == 'y':
macAdress = input("\nEnter the MAC Address to block: \n")
#Open rules.v4 and read if the mac address is allready blocked
with open("/etc/iptables/rules.v4", "r") as f:
data = f.read()
if macAdress.upper() in data:
blockedMac.append(macAdress) #Append the blocked mac address to list blockedMac
print("Allready blocked!")
else:
print(macAdress + " is now being blocked!")
os.system("iptables -A INPUT -p ALL -m mac --mac-source " + macAdress + " -j DROP")
os.system("iptables-save > /etc/iptables/rules.v4")
blockedMac.append(macAdress) #Append the blocked mac address to list blockedMac
#Go back to infinite loop```
From my understanding, you want a while loop that only runs while something is true you could do something like this
loop = 'True'
while loop == 'True':
print('Worked!')
loop = 'False'
Let me know if it is not.

Trying to serve HTML5 <audio> element from Python+SSL to Android Chrome

I have a Python-based web application server; everything was great
with plain HTTP. With HTTPS, everything works perfectly with
all browsers--except Android Chrome. With Chrome, HTML and icons are fine
over HTTPS, but the <audio> element fails to start. I see
Chrome pull one initial byte of the mp3 (presumably its way of testing file
presence), which is served back to it. And then Chrome greys out
the <audio> element.
I've pulled that same single byte using curl, and it works fine:
curl -r 0-1 -k https://localhost:8083/foo.mp3 > foo1.mp3
I've added various delays and flushes, without fixing the problem.
It would seem to not be a content-range issue, as I've also
changed the code to return the full mp3 (with 200 code), with
the same Chrome behavior.
Firefox is happy with it (both Android and Linux), as is Midori (a
Webkit based browser). On Linux, Chrome/Chromium are both happy with
it. Android Chrome--no luck.
I've extracted just the relevant bits of code; I'm assuming there's
some HTTP nicety I'm missing (and, believe me, I've been looking).
To exercise it, plug in a self-signed certificate pair at the
hard-coded files "server.key" and "server.crt". Then put an mp3
of your choice at "foo.mp3" and point your browser at:
https://localhost:8083
TIA for any suggestions! I'm sorry the code runs a little long;
I extracted just the bits to reproduce this. I almost left off
the range support, but didn't want to chase legacy code paths
of Chrome.
#
# debug.py
# Sample code snippet to debug Chrome HTML5 <audio> SSL problem
#
import pdb
import sys, socket, ssl, threading, os, time
from BaseHTTPServer import BaseHTTPRequestHandler
OURMP3 = "foo.mp3"
# Decode a "range:" header option, return
# (offset,length) or None if we don't like
# the region (TBD, multiple ranges and
# multipart)
# We're passed the file's os.stat as well as
# the range: field value.
def decode_range(st, range):
# Byte units, please
if not range.startswith("bytes="):
return None
range = range[6:]
# Single range
if ',' in range:
return None
# Start to offset
if range[0] == '-':
range = range[1:]
if not range.isdigit():
return None
val1 = int(range)
if val1 >= st.st_size:
return None
return (0, val1)
# Offset to end...
elif range[-1] == '-':
range = range[:-1]
if not range.isdigit():
return None
val2 = int(range)
if val2 >= st.st_size:
return None
return (val2, st.st_size - val2)
# Offset1 to offset2
else:
parts = range.split('-')
if len(parts) != 2:
return None
if not all(p.isdigit() for p in parts):
return None
val1 = int(parts[0])
val2 = int(parts[1])
if val1 >= val2:
return None
return (val1, val2-val1)
class Client(BaseHTTPRequestHandler):
# Send the mp3 file OURMP3
def send_mp3(self):
# For simplicity, just a big buffer
f = open(OURMP3, "rb")
st = os.fstat(f.fileno())
buf = f.read()
f.close()
# Partial
ranged = 'range' in self.headers
if ranged:
tup = decode_range(st, self.headers['range'])
assert tup
startoff,nbyte = tup
assert (nbyte + startoff) <= len(buf)
self.send_response(206)
else:
startoff = 0
nbyte = len(buf)
self.send_response(200)
# Headers
self.send_response(200)
self.send_header("Content-type", "audio/mpeg")
self.send_header("Content-Length", nbyte)
if ranged:
self.send_header("Content-Range",
"bytes %d-%d/%d" % (startoff, startoff+nbyte-1, st.st_size))
self.send_header("Last-Modified",
time.asctime(time.localtime(st.st_mtime)))
self.end_headers()
# Let our upper layers write it back (or discard
# it, for HEAD)
return buf[startoff:(startoff+nbyte)]
# Send an HTML5 <audio> player for our mp3
def send_root(self):
buf = \
'''
<html><head><title>Test MP3</title></head>\r
Audio player:<br>\r
<body><audio src="foo.mp3" controls autoplay></audio></body>\r
</html>\r
'''
self.send_response(200)
self.send_header("Content-type", "text/html")
self.send_header("Content-Length", len(buf))
self.end_headers()
return buf
# Process HTTP GET's
def do_GET(self):
sys.stderr.write("GET %r\n" % (self.path,))
path = self.path
# Root; our HTML to play the mp3
if (not path) or (path == '/'):
buf = self.send_root()
# Our mp3
elif path.endswith(OURMP3):
buf = self.send_mp3()
# That's all we serve
else:
self.send_error(404)
return None
# Body?
if buf:
self.wfile.write(buf)
# Dispatch this web client
def serve_client(conn, tup):
h = Client(conn, tup, None)
conn.close()
sys.exit(0)
# Endless server loop on port 8083
def server():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s = ssl.wrap_socket(s,
"server.key", "server.crt",
server_side=True, suppress_ragged_eofs=False,
do_handshake_on_connect=False)
s.bind( ("", 8083) )
s.listen(10)
while True:
conn,tup = s.accept()
sys.stderr.write("client %r\n" % (tup,))
conn.do_handshake()
t = threading.Thread(target=serve_client, args=(conn,tup))
t.start()
if __name__ == "__main__":
server()

Python scan for network IP addresses and macs

ip a output screenshotI am trying to create a script that scans a LAN and obtains the ip address and mac address of all the machines using Python. The script below does this, however it prints the list twice? How could this be achieved, or how could the script below be changed to print the list once(as a dictionary where the ip address is the key and the mac is the value)?
from __future__ import absolute_import, division, print_function
import logging
import scapy.config
import scapy.layers.l2
import scapy.route
import socket
import math
import errno
logging.basicConfig(format='%(asctime)s %(levelname)-5s %(message)s', datefmt='%Y-%m-%d %H:%M:%S', level=logging.DEBUG)
logger = logging.getLogger(__name__)
def long2net(arg):
if (arg <= 0 or arg >= 0xFFFFFFFF):
raise ValueError("illegal netmask value", hex(arg))
return 32 - int(round(math.log(0xFFFFFFFF - arg, 2)))
def to_CIDR_notation(bytes_network, bytes_netmask):
network = scapy.utils.ltoa(bytes_network)
netmask = long2net(bytes_netmask)
net = "%s/%s" % (network, netmask)
if netmask < 16:
logger.warn("%s is too big. skipping" % net)
return None
return net
def scan_and_print_neighbors(net, interface, timeout=1):
logger.info("arping %s on %s" % (net, interface))
try:
ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=True)
for s, r in ans.res:
line = r.sprintf("%Ether.src% %ARP.psrc%")
try:
hostname = socket.gethostbyaddr(r.psrc)
line += " " + hostname[0]
except socket.herror:
# failed to resolve
pass
logger.info(line)
except socket.error as e:
if e.errno == errno.EPERM: # Operation not permitted
logger.error("%s. Did you run as root?", e.strerror)
else:
raise
if __name__ == "__main__":
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
# see http://trac.secdev.org/scapy/ticket/537
logger.warn("skipping %s because scapy currently doesn't support arping on non-primary network interfaces", net)
continue
if net:
scan_and_print_neighbors(net, interface)
Have you tried setting verbose to False?
ans, unans = scapy.layers.l2.arping(net, iface=interface, timeout=timeout, verbose=False)
In addition to setting verbose=False in your scapy.layers.l2.arping(,
import the conf module:
from scapy.all import conf
And add conf.verb=0 just below your if __name__ == "__main__": line:
if __name__ == "__main__":
conf.verb=0
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
EDIT: I think your script is looping once for each "route" defined in your /proc/net/route that hasn't already been explicitly filtered out (i.e. the lines above your continue commands.) My guess is that if you where to execute route -n you'll probably find 2 routes in there that somehow have the same Network and Interface values but something else is differing like Netmask or Gateway.
Anyways, the hackish way to get pass this is to add a break after your call to scan_and_print_neighbors(net, interface) to exit the for-loop.
For example:
if __name__ == "__main__":
for network, netmask, _, interface, address in scapy.config.conf.route.routes:
# skip loopback network and default gw
if network == 0 or interface == 'lo' or address == '127.0.0.1' or address == '0.0.0.0':
continue
if netmask <= 0 or netmask == 0xFFFFFFFF:
continue
net = to_CIDR_notation(network, netmask)
if interface != scapy.config.conf.iface:
# see http://trac.secdev.org/scapy/ticket/537
logger.warn("skipping %s because scapy currently doesn't support arping on non-primary network interfaces", net)
continue
if net:
scan_and_print_neighbors(net, interface)
break

Global name 'bluetooth' is not defined

I am working with the bitalino board and I wanted to print the data with python but when I run the proper code, it shows me the message
Global name 'bluetooth' is not defined
According to my pc the board is connected via bluetooth. I don't know what the problem is, could you help me?
Pd: I am using Mac OS X.
This is part of the code where the problem may be:
try:
import bluetooth
from bluetooth import discover_devices
except ImportError:
pass
import serial
from serial.tools import list_ports
import time
import math
import numpy
class BITalino(object):
def __init__(self):
"""
BITalino class: interface to the BITalino hardware.
"""
self.socket = None
self.analogChannels = []
self.number_bytes = None
self.macAddress = None
self.serial = False
def find(self, serial=False):
"""
Search for bluetooth devices nearby
Output: tuple with name and mac address of each device found
"""
try:
if serial:
nearby_devices = list(port[0] for port in list_ports.comports() if 'bitalino' or 'COM' in port[0])
else:
nearby_devices = discover_devices(lookup_names=True)
return nearby_devices
except:
return -1
def open(self, macAddress=None, SamplingRate=1000):
"""
Connect to bluetooth device with the mac address provided.
Configure the sampling Rate.
Kwargs:
macAddress (string): MAC address of the bluetooth device
SamplingRate(int): Sampling frequency (Hz); values available: 1000, 100, 10 and 1
Output: True or -1 (error)
"""
Setup = True
while Setup:
if macAddress != None:
try:
if ":" in macAddress and len(macAddress) == 17:
self.socket = bluetooth.BluetoothSocket(bluetooth.RFCOMM)
self.socket.connect((macAddress, 1))
else:
self.socket = serial.Serial(macAddress, 115200)
self.serial = True
time.sleep(2)
# Configure sampling rate
if SamplingRate == 1000:
variableToSend = 0x03
elif SamplingRate == 100:
variableToSend = 0x02
elif SamplingRate == 10:
variableToSend = 0x01
elif SamplingRate == 1:
variableToSend = 0x00
else:
self.socket.close()
raise TypeError, "The Sampling Rate %s cannot be set in BITalino. Choose 1000, 100, 10 or 1." % SamplingRate
return -1
variableToSend = int((variableToSend<<6)|0x03)
self.write(variableToSend)
Setup = False
except Exception, e:
print e
return -1
else:
raise TypeError, "A MAC address or serial port is needed to connect"
return -1
else:
self.macAddress = macAddress
return True
Hopefully this will help:
http://lightblue.sourceforge.net/
This is an API for python's bluetooth feature
It's generally better to let the import fail if something is wrong so I would remove the try..except and just do a normal import.
The only reason to use it in an import if you are indifferent about what library you want to use:
try:
import json
except ImportError:
import simplejson as json

How do I recover from a serialException using pySerial

I have an application that reads and transmits data to a device connected via USB. I'm using pySerial to facilitate this communication. Everything works fine until the USB cable is unplugged from the PC and an exception is thrown. Once the cable is plugged back in, I can't seem to recover and reconnect to my device. The only way for me to recover is to close down the application and unplug and plug the cable in again. Any help in understanding what's going on would be much appreciated.
This is basic test code that I'm useing to help me understand the process.
# Class used to communicate with USB Dongle
import serial
import time
import sys
class LPort:
def __init__(self, port=0):
"initialize the LPort class"
self.error = ""
self.traffic = ""
self.dest = None
if port == None:
self.simulation = True
else:
self.simulation = False
self.port = port # serial port we should use
self.reset()
self.time = time.time()
def reInit(self):
self.close()
def reset(self):
"flush port, reset the LPort, initialize LPort"
if self.simulation:
r = "LPort simulator"
else:
self.port.flushInput()
self.port.flushOutput()
self.fail = False
self.command("/H1")
self.dest = None
r = "reset"
self.error = ""
self.traffic = ""
return r
def status(self):
"return accumulated status info, reset collection"
s = self.error
self.error = ""
return s
def data(self):
"return accumulated traffic data, reset collection"
s = self.traffic
self.traffic = ""
return s
def set_dest(self, addr):
"set the destination address (if necessary)"
if addr != self.dest:
self.dest = addr
self.command("/O")
r = self.command("/D%02X" % addr)
if r != "*":
self.dest = None
self.error += r
else:
r = True
return r
def checksum(self, bytes):
"calculate the CRC-8 checksum for the given packet"
crc_table = [
# this table is taken from the CP rectifier code
0x00,0x07,0x0E,0x09,0x1C,0x1B,0x12,0x15,0x38,0x3F,
0x36,0x31,0x24,0x23,0x2A,0x2D,0x70,0x77,0x7E,0x79,
0x6C,0x6B,0x62,0x65,0x48,0x4F,0x46,0x41,0x54,0x53,
0x5A,0x5D,0xE0,0xE7,0xEE,0xE9,0xFC,0xFB,0xF2,0xF5,
0xD8,0xDF,0xD6,0xD1,0xC4,0xC3,0xCA,0xCD,0x90,0x97,
0x9E,0x99,0x8C,0x8B,0x82,0x85,0xA8,0xAF,0xA6,0xA1,
0xB4,0xB3,0xBA,0xBD,0xC7,0xC0,0xC9,0xCE,0xDB,0xDC,
0xD5,0xD2,0xFF,0xF8,0xF1,0xF6,0xE3,0xE4,0xED,0xEA,
0xB7,0xB0,0xB9,0xBE,0xAB,0xAC,0xA5,0xA2,0x8F,0x88,
0x81,0x86,0x93,0x94,0x9D,0x9A,0x27,0x20,0x29,0x2E,
0x3B,0x3C,0x35,0x32,0x1F,0x18,0x11,0x16,0x03,0x04,
0x0D,0x0A,0x57,0x50,0x59,0x5E,0x4B,0x4C,0x45,0x42,
0x6F,0x68,0x61,0x66,0x73,0x74,0x7D,0x7A,0x89,0x8E,
0x87,0x80,0x95,0x92,0x9B,0x9C,0xB1,0xB6,0xBF,0xB8,
0xAD,0xAA,0xA3,0xA4,0xF9,0xFE,0xF7,0xF0,0xE5,0xE2,
0xEB,0xEC,0xC1,0xC6,0xCF,0xC8,0xDD,0xDA,0xD3,0xD4,
0x69,0x6E,0x67,0x60,0x75,0x72,0x7B,0x7C,0x51,0x56,
0x5F,0x58,0x4D,0x4A,0x43,0x44,0x19,0x1E,0x17,0x10,
0x05,0x02,0x0B,0x0C,0x21,0x26,0x2F,0x28,0x3D,0x3A,
0x33,0x34,0x4E,0x49,0x40,0x47,0x52,0x55,0x5C,0x5B,
0x76,0x71,0x78,0x7F,0x6A,0x6D,0x64,0x63,0x3E,0x39,
0x30,0x37,0x22,0x25,0x2C,0x2B,0x06,0x01,0x08,0x0F,
0x1A,0x1D,0x14,0x13,0xAE,0xA9,0xA0,0xA7,0xB2,0xB5,
0xBC,0xBB,0x96,0x91,0x98,0x9F,0x8A,0x8D,0x84,0x83,
0xDE,0xD9,0xD0,0xD7,0xC2,0xC5,0xCC,0xCB,0xE6,0xE1,
0xE8,0xEF,0xFA,0xFD,0xF4,0xF3]
for i in range(len(bytes)):
b = int(bytes[i])
if i == 0: chksum = crc_table[b]
else: chksum = crc_table[chksum ^ b]
return chksum
def command(self, cmd):
"transmit distinct commands to unit, and accept response"
if self.simulation:
r = "*"
else:
try:
self.port.write(cmd + chr(13))
except serial.serialutil.SerialTimeoutException:
r = "/TO"
return r
except:
print "Unexpected error:", sys.exc_info()[0]
r = "/Unknown"
return r
r = ""
eol = False
while True:
c = self.port.read(1)
if not c:
r = "/FAIL " + r + " " + cmd
self.error = r
break
else:
r += c
ordc = ord(c)
if ordc == 13 or ordc == 42:
break
return r
def checkRawDataForErrors(self, raw, errors = []):
errorCodes = {'/SNA':'Slave Not Acknowledging',
'/I81':'Busy, Command Ignored',
'/I88':'Connection Not Open',
'/I89':'Invalid Command Argument',
'/I8A':'Transmit Not Active',
'/I8F':'Invalid Command',
'/I90':'Buffer Overflow',
'/DAT':'Data Error',
'/BADPEC':'Bad PEC Value',
'/NO_MRC':'No Master Read Complete Signal',
'/FAIL':'General Failure',
'/LEN':'Data Length Error'}
for ekey, eval in errorCodes.items():
if ekey in raw:
errors.append(eval)
return errors
# self-testing module
if __name__ == "__main__":
com = serial.Serial(port=4, baudrate=115200, timeout=1, xonxoff=0)
if com:
port = LPort(com)
print port
time.sleep(5)
port = LPort(com)
print "/V =", port.command("/V")
print "/V", port.data(), port.status()
print "/O =", port.command("/O")
print "/O", port.data(), port.status()
print "/A =", port.command("/A")
print "/A", port.data(), port.status()
print "/L =", port.command("/L")
print "/L", port.data(), port.status()
com.close()
else:
print "cannot open com port"
UPDATE:
The following is the code around the creatfile() in serialwin32.py which returns the following message:
serial.serialutil.SerialException: could not open port COM5: [Error 2] The system cannot find the file specified.
self.hComPort = win32.CreateFile(port,
win32.GENERIC_READ | win32.GENERIC_WRITE,
0, # exclusive access
None, # no security
win32.OPEN_EXISTING,
win32.FILE_ATTRIBUTE_NORMAL | win32.FILE_FLAG_OVERLAPPED,
0)
if self.hComPort == win32.INVALID_HANDLE_VALUE:
self.hComPort = None # 'cause __del__ is called anyway
raise SerialException("could not open port %s: %s" % (self.portstr, ctypes.WinError()))
Assuming your device is well-behaved, all you must do is this:
close your serial port (serial.Serial instance)
find the COMX name of your port again
open the serial port
The 2nd part is problematic because Windows tries to be clever. In your case the following happens:
USB device is connected and is assigned name COM2
Your program opens the device
USB disconnects
USB reconnects quickly before your program noticed that device died
Windows sees that COM2 is busy and assigns a different name to this USB device
(optional) your program closes the device
your program tries to open COM2 again, but there's no hardware at that name
The are way to get around Windows being clever -- you can specifically assign fixed COMX name to this device in Device Manager, COM ports, your port, advanced options.
Another option is to detect device dying very fast and closing the file handle. If you are lucky then by the time device reconnects original COM2 is free again.
Yet another option is to use a USB-serial converter from another manufacturer that uses another driver. Somehow COMX letter assignment is driver-specific. Better drivers may give you a stable name.
I've come across this problem as well. Sometimes my program has locked up when the device is plugged in again.
NB. I have fixed the COMx name of the port as mentioned by #qarma
I've rearranged my program so that as soon as an exception is thrown from the read() or write() methods of Serial I stop calling those methods.
I then have a function which periodically retries opening the port to try to detect when the device has been plugged in again.
This function creates a new instance of Serial with the same parameters as the original and tries to open it:
def try_to_open_new_port(self):
ret = False
test = serial.Serial(baudrate=9600, timeout=0, writeTimeout=0)
test.port = self.current_port_name
try:
test.open()
if test.isOpen():
test.close()
ret = True
except serial.serialutil.SerialException:
pass
return ret
A return of True indicates that the port is present once again.

Categories

Resources