user1112600
user1112600

Reputation: 11

python setsockopt what is worng

what is wrong in that code:

def iec104(dst):
     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
     time = struct.pack('ii', int(2), 0)
     sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, time)

try:
    sock.connect(dst)
except:
    return '', -1


dst = (ip, 2404)
recv, asdu_addr = iec104(dst)
print "ip: {0}, recv: {1}, asdu_addr: {2}".format(ip, 
recv.encode('hex'), asdu_addr)

error:

    sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, time)
    File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/socket.py", line 228, in meth
return getattr(self._sock,name)(*args)
socket.error: [Errno 22] Invalid argument

Is there any bug in "socket.SO_RCVTIMEO". Is a kind of server who wont to lisent and have a timeout Thanks

Upvotes: 1

Views: 2738

Answers (2)

bitmous
bitmous

Reputation: 440

Sam Hartman's advice is sound. The absolute dead-simplest way to go about this is;

import sys, socket, struct
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
if sys.maxsize > 2**32:
  time = struct.pack(str("ll"), int(2), int(0))
else:
  time = struct.pack(str("ii"), int(2), int(0))
sock.setsockopt(socket.SOL_SOCKET, socket.SO_RCVTIMEO, time)

Note this is not foolproof. sys.maxsize may report incorrectly if mixing architectures (32-bit python on 64-bit OS, etc.).

Upvotes: 1

Sam Hartman
Sam Hartman

Reputation: 6489

Struct timeval is 16 bites on 64-bit linux. More generally, I think you should be using 64-bit integers in your struct call at least on most 64-bit platforms. It's ugly that this is architecture and OS dependent. So try struct.pack('ll',int(2),int(0))

Upvotes: 1

Related Questions