Python Forum
Working socket() program...isn't
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Working socket() program...isn't
#1
I'm pretty new to Python, and newer still to socket() but I've been working on learning it. I implemented the "Echo Client and Server" from https://realpython.com/python-sockets/#tcp-sockets and it was working fine Aug 11. It doesn't do much but it's a start. I've been away from this code since then, working on a RAW socket test but I haven't touched this one. I verified in my ssh console logs that everything in the py code is the same, and it's the same version of Python (3.6.6). There is a possibility that *something* changed - the CentOS 7 system on which this lives was added to our AD Domain a couple weeks after this was working. I put this in Networking in case it's particular to socket().

Code:
#!/usr/bin/python3.6
"""
sniffsms.py: listen on eth1 for traffic to the SMS modem device, and send a copy to the 
other host running the 'receive' end
"""

import socket, sys
import time
import logging

HOST = '127.0.0.1'  # Standard loopback interface address (localhost)
PORT = 65432        # Port to listen on (non-privileged ports are > 1023)

if len(sys.argv) < 2:

        print("server or client, idiot.")

        sys.exit(2)

if sys.argv[1] == 'server':

        logging.basicConfig(filename='/home/a-ptrivino/sserver.log', format='%(asctime)s %(message)s', level=logging.DEBUG)

        logging.info("Starting server.")

        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as transfer:

                transfer.bind((HOST, PORT))

                transfer.listen()

                logging.info("Server listening on tcp/" + PORT + ".")

                conn, client = transfer.accept()

                with conn:

                        logging.info("Connected to " + str(client))

                        while True:

                                data = conn.recv(1024)

                                if not data:

                                        break

                                conn.sendall(data)

elif sys.argv[1] == 'client':

        logging.basicConfig(filename='/home/a-ptrivino/sclient.log', format='%(asctime)s %(message)s', level=logging.DEBUG)

        logging.info("Starting client.")

        connected = False

        with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as sender:

                while not connected:

                        try:

                                sender.connect((HOST, PORT))

                                connected = True

                        except ConnectionRefusedError:

                               logging.info("Server not connected.")

                                time.sleep(3)

                sender.sendall(b'Test message.')

                data = sender.recv(1024)

        logging.info("Got back " + repr(data))

else:

        print("server or client, idiot.")
However, when I try to run it (always with sudo) I get this:

Output:
(pagesniff) [a-ptrivino@insecpydev pagesniff]$ sudo python sniffsms.py.bak server [sudo] password for a-ptrivino: Traceback (most recent call last): File "sniffsms.py.bak", line 26, in <module> with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as transfer: AttributeError: __exit__ (pagesniff) [a-ptrivino@insecpydev pagesniff]$
Can anyone say why this might have stopped working with no (specifically known) changes? BTW it fails with the same error on both 'server' and 'client' at the 'with' line.

Paul
Reply
#2
Can you log the output of dir(socket.socket()) ?
Reply
#3
(Nov-01-2019, 06:32 AM)Gribouillis Wrote: Can you log the output of dir(socket.socket()) ?

Quote:Python 3.6.6 (default, Aug 13 2018, 18:24:23)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-28)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> dir(socket.socket())
['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_accept', '_check_sendfile_params', '_closed', '_decref_socketios', '_io_refs', '_real_close', '_sendfile_use_send', '_sendfile_use_sendfile', 'accept', 'bind', 'close', 'connect', 'connect_ex', 'detach', 'dup', 'family', 'fileno', 'get_inheritable', 'getpeername', 'getsockname', 'getsockopt', 'gettimeout', 'listen', 'makefile', 'proto', 'recv', 'recv_into', 'recvfrom', 'recvfrom_into', 'recvmsg', 'recvmsg_into', 'send', 'sendall', 'sendfile', 'sendmsg', 'sendmsg_afalg', 'sendto', 'set_inheritable', 'setblocking', 'setsockopt', 'settimeout', 'shutdown', 'timeout', 'type']
>>>

I know it has to do with context management, of which I understand the theory, and a lot of my searches for the error mention this. But what's really confounding is that this worked before and I haven't knowingly changed anything.

Thanks for looking.
Reply
#4
Try to output the same thing from within your program, just before the with statement because obviously a strange object is created by your call to socket.socket() in the with statement.
Reply
#5
(Nov-01-2019, 05:45 PM)Gribouillis Wrote: Try to output the same thing from within your program, just before the with statement because obviously a strange object is created by your call to socket.socket() in the with statement.

Good call, obviously *something* has changed, __exit__ is no longer there:
Output:
(pagesniff) [a-ptrivino@insecpydev pagesniff]$ sudo python sniffsms.py server ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_sock', 'accept', 'bind', 'close', 'connect', 'connect_ex', 'dup', 'family', 'fileno', 'getpeername', 'getsockname', 'getsockopt', 'gettimeout', 'listen', 'makefile', 'proto', 'recv', 'recv_into', 'recvfrom', 'recvfrom_into', 'send', 'sendall', 'sendto', 'setblocking', 'setsockopt', 'settimeout', 'shutdown', 'type'] Traceback (most recent call last): File "sniffsms.py", line 28, in <module> with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as transfer: AttributeError: __exit__ (pagesniff) [a-ptrivino@insecpydev pagesniff]$
So I'm guessing somehow the socket() in the program is somehow being overridden since it's different from the one I tried in the interpreter.
Reply
#6
Support for using sockets with the context manager (with-block) was added in 3.2. You said you've checked that they're both at least 3.6, but could you double check the python versions involved?

I wouldn't think that'd be the issue, though, as the error would probably mention __enter__ instead of __exit__.

Do you happen to have a file named "socket.py" in your path? Maybe you're importing the wrong thing...
Reply
#7
(Nov-01-2019, 07:14 PM)nilamo Wrote: Support for using sockets with the context manager (with-block) was added in 3.2. You said you've checked that they're both at least 3.6, but could you double check the python versions involved?

I wouldn't think that'd be the issue, though, as the error would probably mention __enter__ instead of __exit__.

Do you happen to have a file named "socket.py" in your path? Maybe you're importing the wrong thing...

FYI (and maybe this is obvious from my 'outputs') I'm running in a virtual environment for Py3, but I see where you're going with this. So I added

print(sys.version_info)
print(socket.__file__)
just above the first 'if', adn that yields:

Output:
(pagesniff) [a-ptrivino@insecpydev pagesniff]$ sudo python sniffsms.py server sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0) /usr/lib64/python2.7/socket.pyc ['__class__', '__delattr__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_sock', 'accept', 'bind', 'close', 'connect', 'connect_ex', 'dup', 'family', 'fileno', 'getpeername', 'getsockname', 'getsockopt', 'gettimeout', 'listen', 'makefile', 'proto', 'recv', 'recv_into', 'recvfrom', 'recvfrom_into', 'send', 'sendall', 'sendto', 'setblocking', 'setsockopt', 'settimeout', 'shutdown', 'type'] Traceback (most recent call last): File "sniffsms.py", line 31, in <module> with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as transfer: AttributeError: __exit__ (pagesniff) [a-ptrivino@insecpydev pagesniff]$
My path (from 'env')
Output:
PATH=/home/a-ptrivino/Py3hole/pagesniff/bin:/usr/local/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/opt/puppetlabs/bin:/home/a-ptrivino/.local/bin:/home/a-ptrivino/bin
Thanks for this, BTW...

I kinda see where this is headed. So I su'd and navigated to the directory, and ran it as root:

Output:
(pagesniff) [root@insecpydev pagesniff]# python sniffsms.py server sys.version_info(major=3, minor=6, micro=6, releaselevel='final', serial=0) /usr/lib64/python3.6/socket.py ['__class__', '__del__', '__delattr__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__slots__', '__str__', '__subclasshook__', '__weakref__', '_accept', '_check_sendfile_params', '_closed', '_decref_socketios', '_io_refs', '_real_close', '_sendfile_use_send', '_sendfile_use_sendfile', 'accept', 'bind', 'close', 'connect', 'connect_ex', 'detach', 'dup', 'family', 'fileno', 'get_inheritable', 'getpeername', 'getsockname', 'getsockopt', 'gettimeout', 'listen', 'makefile', 'proto', 'recv', 'recv_into', 'recvfrom', 'recvfrom_into', 'recvmsg', 'recvmsg_into', 'send', 'sendall', 'sendfile', 'sendmsg', 'sendmsg_afalg', 'sendto', 'set_inheritable', 'setblocking', 'setsockopt', 'settimeout', 'shutdown', 'timeout', 'type'] ^CTraceback (most recent call last): File "sniffsms.py", line 39, in <module> conn, client = transfer.accept() File "/usr/lib64/python3.6/socket.py", line 205, in accept fd, addr = self._accept() KeyboardInterrupt (pagesniff) [root@insecpydev pagesniff]#
It runs fine. Wall Wall Wall
Reply
#8
Quote:
(pagesniff) [a-ptrivino@insecpydev pagesniff]$ sudo python sniffsms.py server
sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0)
/usr/lib64/python2.7/socket.pyc

So, as not-root, python resolves to 2.7. What about sudo python3 sniffsms.py server to try to force python3?
Reply
#9
I don't think sudo is the correct way to force python 3. Running as administrator serves radically different purposes than running another version of python.
Reply
#10
(Nov-01-2019, 08:58 PM)nilamo Wrote:
Quote:
(pagesniff) [a-ptrivino@insecpydev pagesniff]$ sudo python sniffsms.py server
sys.version_info(major=2, minor=7, micro=5, releaselevel='final', serial=0)
/usr/lib64/python2.7/socket.pyc

So, as not-root, python resolves to 2.7. What about sudo python3 sniffsms.py server to try to force python3?

(Nov-01-2019, 09:46 PM)Gribouillis Wrote: I don't think sudo is the correct way to force python 3. Running as administrator serves radically different purposes than running another version of python.

No, by running in the virtual environment (created with "python3.6 -m venv pagesniff" in this case) I get python v3.6.6 - you can see that from the first dir(socket.socket()) I posted (actually you can't, I cut that line off, but all I entered was 'python' and I get 3.6). Using sudo is necessary at this point to be able to use socket() - once this is fully put together it will be a systemd service and that need goes away.

Hold up a bit on this - I just spoke with my Linux admin and he doesn't think it was the AD Domain add process, but possibly adding the system to our Ansible and/or Satelite setup that may have bit me. One thing I will try is creating a new virtual environment and see if THAT makes it happier.

Paul
Reply


Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020