Search code examples
pythonsocketsmakefileioerror

Python Socket Makefile Error I/O operation on closed file


I want to use socket.makefile method instead of socket.send or socket.recv but I face this error I/O operation on closed file.

from socket import *

s = socket(AF_INET,SOCK_STREAM)
s.connect(('localhost',4321))
read = s.makefile('r',)
write = s.makefile('w')

def send(cmd):
    # print(cmd)
    write.write(cmd + '\n')
    write.flush()

with s,read,write:
    send('TEST')
    send('LIST')
    while True:
        send("DONE")
        data = read.readline()
        if not data: break
        item = data.strip()
        if item == 'DONE':
            break
        elif item.startswith("--player-"):
            print(f"player{item.split('--player-')[1]}")
        print(f'item: {item}')
    send('OTHER') 
send("GGGGGGGG")  #I want to send this part in another place .I dont want to in with s,read,write:
print(read.readline().strip())

Thanks for Help In Advance.


Solution

  • with statement has such behaviour:

    with s,read,write:
        # smth to do
    # <--------------- s, read and write are closed here
    

    Therefore the subsequent send is invoked on closed object.

    You need not use with statement:

    # ...
    send('TEST')
    send('LIST')
    while True:
        send("DONE")
        data = read.readline()
        if not data: break
        item = data.strip()
        if item == 'DONE':
            break
        elif item.startswith("--player-"):
            print(f"player{item.split('--player-')[1]}")
        print(f'item: {item}')
    send('OTHER')
    send("GGGGGGGG")  # write is open here
    print(read.readline().strip())
    

    Or recreate write and read files in another place. But at the same time, exclude the socket s from the first with so that the socket does not close.

    with read, write:  # <-- s excluded
        send('TEST')
        send('LIST')
        while True:
            send("DONE")
            data = read.readline()
            if not data: break
            item = data.strip()
            if item == 'DONE':
                break
            elif item.startswith("--player-"):
                print(f"player{item.split('--player-')[1]}")
            print(f'item: {item}')
        send('OTHER')
    # ...
    read = s.makefile('r', )  # <-- recreate files
    write = s.makefile('w')
    send("GGGGGGGG")