Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added option to enable or disable TCP_QUICKACK #36

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,3 +68,11 @@ and:
print(instr.ask("*IDN?"))
# returns 'AGILENT TECHNOLOGIES,MSO-X 3014A,MY********,02.35.2013061800'

In case of double acks and retransmissions in Unix Like Systems, disable TCP_QUICKACK is an option:

import vxi11
instr = vxi11.Instrument("192.168.1.104")
instr.disable_tcp_quickack()
print(instr.ask("*IDN?"))
# returns 'AGILENT TECHNOLOGIES,MSO7104A,MY********,06.16.0001'
instr.close()
18 changes: 14 additions & 4 deletions vxi11/rpc.py
Original file line number Diff line number Diff line change
Expand Up @@ -251,8 +251,9 @@ def recvrecord(sock):
# Client using TCP to a specific port

class RawTCPClient(Client):
def __init__(self, host, prog, vers, port):
def __init__(self, host, prog, vers, tcp_quickack, port):
Client.__init__(self, host, prog, vers, port)
self.tcp_quickack = tcp_quickack
self.connect()

def connect(self):
Expand All @@ -264,6 +265,8 @@ def close(self):

def do_call(self):
call = self.packer.get_buf()

self.configure_socket_options()
sendrecord(self.sock, call)
while True:
reply = recvrecord(self.sock)
Expand All @@ -280,6 +283,13 @@ def do_call(self):
else:
# xid larger than expected - packet from the future?
raise RPCError('wrong xid in reply %r instead of %r' % (xid, self.lastxid))

#Reset tcp_quickack case it is 0. If tcp_quickack is 1, socket do it automatically after recv or send operations
#Does nothing in Windows OS
def configure_socket_options(self):
if os.name != 'nt':
if self.tcp_quickack == 0:
self.sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_QUICKACK, 0)


# Client using UDP to a specific port
Expand Down Expand Up @@ -489,7 +499,7 @@ def callit(self, ca):
class TCPPortMapperClient(PartialPortMapperClient, RawTCPClient):

def __init__(self, host):
RawTCPClient.__init__(self, host, PMAP_PROG, PMAP_VERS, PMAP_PORT)
RawTCPClient.__init__(self, host, PMAP_PROG, PMAP_VERS, 1, PMAP_PORT)
PartialPortMapperClient.__init__(self)


Expand All @@ -511,14 +521,14 @@ def __init__(self, bcastaddr):

class TCPClient(RawTCPClient):

def __init__(self, host, prog, vers, port=0):
def __init__(self, host, prog, vers, tcp_quickack, port=0):
if port == 0:
pmap = TCPPortMapperClient(host)
port = pmap.get_port((prog, vers, IPPROTO_TCP, 0))
pmap.close()
if port == 0:
raise RPCError('program not registered')
RawTCPClient.__init__(self, host, prog, vers, port)
RawTCPClient.__init__(self, host, prog, vers, tcp_quickack, port)


class UDPClient(RawUDPClient):
Expand Down
28 changes: 25 additions & 3 deletions vxi11/vxi11.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,10 +393,10 @@ def done(self):


class CoreClient(rpc.TCPClient):
def __init__(self, host, port=0):
def __init__(self, host, tcp_quickack, port=0):
self.packer = Packer()
self.unpacker = Unpacker('')
rpc.TCPClient.__init__(self, host, DEVICE_CORE_PROG, DEVICE_CORE_VERS, port)
rpc.TCPClient.__init__(self, host, DEVICE_CORE_PROG, DEVICE_CORE_VERS, tcp_quickack, port)

def create_link(self, id, lock_device, lock_timeout, name):
params = (id, lock_device, lock_timeout, name)
Expand Down Expand Up @@ -574,6 +574,7 @@ def __init__(self, host, name = None, client_id = None, term_char = None):
self.client_id = client_id
self.term_char = term_char
self.lock_timeout = 10
self._tcp_quickack = 1
self.timeout = 10
self.abort_port = 0
self.link = None
Expand Down Expand Up @@ -607,13 +608,34 @@ def lock_timeout(self, val):
self._lock_timeout = val
self._lock_timeout_ms = int(val * 1000)

@property
def tcp_quickack(self):
return self._tcp_quickack

def enable_tcp_quickack(self):
#Enable Socket TCP_QUICKACK. This is enabled by default in the socket class.
#Should be enabled/disabled before open()
if self.client is None:
self._tcp_quickack = 1
else:
raise Vxi11Exception("client already oppened! Use it before open the connection!")

def disable_tcp_quickack(self):
#Disable Socket TCP_QUICKACK. This should be disabled if your connection is
#having a lot of double acks and retransmissions. Should be enabled/disabled before open()
#This does nothing for Windows OS
if self.client is None:
self._tcp_quickack = 0
else:
raise Vxi11Exception("client already oppened! Use it before open the connection!")

def open(self):
"Open connection to VXI-11 device"
if self.link is not None:
return

if self.client is None:
self.client = CoreClient(self.host)
self.client = CoreClient(self.host, self.tcp_quickack)

self.client.sock.settimeout(self.timeout+1)
error, link, abort_port, max_recv_size = self.client.create_link(
Expand Down