I have the following script and I'm trying to make it asynchronous. It works fine as a client to connect through TCP and send the text file. However, I'm executing it from another software program, and it is slowing down the program I'm running it from (hence the need for async). My aim is to get the script to run in it's own background thread, so that it doesnt affect the program it is being executed from.
I've tried adding asyncore, but I just keep getting errors and it wont seem to connect. I've also tried threading, but cant get this to work either. Would be grateful for any pointers as to how to make this asynchronous
Ive tried using the tutorial here - http://www.mechanicalcat.net/richard/log/Python/A_simple_asyncore__echo_server__example However, the architecture of their script is so different to mine that I can't seem to incorporate it into my script.
import socket
import struct
import sys
import os
import time
import os.path
_MAX_BLOCK_SIZE = 1448
_PORT = 8002
IP_ADDRESS = '192.168.1.5'
FILE = sys.path[0] + "/MyFile.txt"
class FileSender(object):
def __init__(self, host):
self.__host = IP_ADDRESS
def __Pad(self, buf):
"""Returns copy of buf padded with NULLs to make its length a multiple of 4 bytes."""
if len(buf) % 4 == 0:
return buf
pad_buf = ""
for i in range(4 - (len(buf) % 4)):
pad_buf += "\x00"
return buf + pad_buf
def __FormatInt(self, int):
"""Returns string containing 32-bit integer in network byte order."""
return struct.pack("!i", int)
def Send(self, buf):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.connect((self.__host, _PORT))
padded_buf = self.__Pad(buf)
# Send header packet.
s.send("%s%s%s%s" % (self.__FormatInt(16 + len(padded_buf)),
self.__Pad("/txtl"),
self.__Pad(",b"),
self.__FormatInt(len(buf))))
# Send data packets.
bytes_sent = 0
while (bytes_sent < len(padded_buf)):
bytes_to_send = len(padded_buf) - bytes_sent
assert bytes_to_send % 4 == 0
bytes_this_block = min(_MAX_BLOCK_SIZE, bytes_to_send)
s.send(padded_buf[bytes_sent:(bytes_sent + bytes_this_block)])
bytes_sent += bytes_this_block
s.close()
return bytes_sent
def main(argv):
sendtextfile = FileSender(IP_ADDRESS)
# Read input data.
input_file = open(_FILE)
data = input_file.read().strip()
input_file.close()
datasend = data[:-7]
bytes_sent = sendtextfile.Send(datasend)
if __name__ == "__main__":
main(sys.argv)
Threads would be the approach I would use. Try this:
thread = threading.Thread(target = sendtextfile.Send, args = (datasend,))
thread.start()