0

I'm writing a small Python code that communicates over a socket but I'm having trouble making it so that sending and receiving are absolutely independent actions, i.e. not having to wait for a response in order to be able to send another message. My current code is as follows:

#!/usr/bin/python3
import argparse
import json
import socket
import time
import readline

parser = argparse.ArgumentParser(description='Client')
parser.add_argument("address", metavar= "Address", type=str,nargs=1, help="Server IP")
parser.add_argument("port",metavar="Port", type=str, nargs=1, help="Port to use")
args = parser.parse_args()
addr = args.address[0]
port = int(args.port[0])
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
print("Connecting to {0} on port {1}".format(addr, port))
try:
    sock.connect((addr, port))
    print("Successfully connected to {0}".format(addr))
except Exception as e:
    raise(e)


sock.settimeout(60)
while True:
    msg = input("{0} | Out: ".format(time.strftime("%H:%M:%S")))
    words = msg.split(" ")
    if(words[0] == "connmobi"):
        words = "connect MOBIPIN-02000152 D4:F5:13:6B:77:A6".split(" ")
    data = json.dumps({"command":words[0],"args": [word for word in words[1:]]})
    sock.send("{0}\n".format(data).encode())
    try:
        data = sock.recv(1024).decode().strip('\n')
    except socket.timeout:
        continue

    print("{0} | In: {1}".format(time.strftime("%H:%M:%S"), data))
    if data == "bye":
        sock.close()
        print("Socket closed")
        break

How can I 'separate' the actions of receiving and reading from the socket?

Bernardo Meurer
  • 2,295
  • 5
  • 31
  • 52
  • 1
    Try using select.select https://docs.python.org/2/library/select.html?highlight=select.select#select.select or using multithreading in order to achieve a non-blocking socket. (You can also set the timeout to a lower value but this is less preferable) – pystudent Mar 08 '16 at 18:57
  • @pystudent I'll check those out, the last solution doesn't work because some things take an expected while to respond. – Bernardo Meurer Mar 08 '16 at 18:58
  • @pystudent Also how would I make use of multithreading without running into issues from the port being busy? – Bernardo Meurer Mar 08 '16 at 19:04
  • Take a look at this http://stackoverflow.com/questions/3329641/how-do-multiple-clients-connect-simultaneously-to-one-port-say-80-on-a-server it may help you get a better understanding. I would go with the other option though, it is more efficient, and in my opinion, also cleaner. (using the select module). – pystudent Mar 08 '16 at 19:13

1 Answers1

0

This is by no means a simple solution, but you could take a look into python asyncio. https://docs.python.org/3/library/asyncio-protocol.html

These modules are specifically for asynchronous handling of sockets. After a quick search I found an example that might help you. https://gist.github.com/dbehnke/c8f64cb6e67afff437c1

zerox1212
  • 166
  • 1
  • 7