0

I'm building an IRC bot in Python for fun. It is supposed to accept commands prefixed with '!' and act on them. The function below is used to parse commands received in an IRC message.

def parse_cmd(self, sender):
    #Admin Commands
    if sender == self.owner:
        if self.command == 'quit':
            send_bufr = "QUIT %s\r\n" %(self.channel)
            self.sock.send(bytearray(send_bufr, "utf-8"))
            self.sock.close()
            sys.exit(1)
        if self.command == 'hi':
            print("Run: Hi")
            send_bufr = "PRIVMSG %s :Hello %s" %(self.channel, sender)
            print(send_bufr)
            self.sock.send(bytearray(send_bufr, "utf-8"))
            return
        else:
            return
    else:
        return

The exclamation points are parsed earlier and the function uses self.command as the command which is also set earlier. The following code is used to set the USER, NICK, and to join a channel and self.sock.send works fine here:

    #Send NICK self.nick to set NICK
    send_bufr = ("NICK %s \r\n") %(self.nick)
    self.sock.send(bytearray(send_bufr, "utf-8"))
    print("Set Nick to %s" %(self.nick))

    #Send USER to set USER
    send_bufr = ("USER %s 8 * :S0lder \r\n") %(self.nick)
    self.sock.send(bytearray(send_bufr, "utf-8"))
    print("Set USER to %s 8 :S0lder" %(self.nick))

    #JOIN self.channel
    send_bufr = ("JOIN %s \r\n") %(self.channel)
    self.sock.send(bytearray(send_bufr, "utf-8"))
    print("Joined %s" %(self.channel))
    time.sleep(5)

However In the function earlier and any instances of self.sock.send() after the initial connection are not sent until the '!quit' command is given, at which point all of the messages that were supposed to be sent earlier are sent. Why is this? Am I misunderstanding the proper way to use sockets?

Edit: I'm connected to the same channel with an IRC client and the messages appear in the channel only after I give the !quit command.

Michael Smith
  • 1,847
  • 2
  • 19
  • 19
  • 1
    What's your receive code look like? The problem might be there, not here in the send code. – payne Feb 01 '11 at 21:02
  • 2
    I don't know IRC, but your response to the hi command seems problematic. Shouldn't it include a terminator, such as \r\n? – Winston Ewert Feb 01 '11 at 21:07
  • My receive code works fine as the debugging print() function I added before the socket.send() prints indicating that the command is received. – Michael Smith Feb 01 '11 at 21:09
  • Much thanks to Winston Ewert as this was the issue. A stupid mistake on my part. – Michael Smith Feb 01 '11 at 21:11
  • Off-topic: You should rather use [`socket.sendall`](http://docs.python.org/dev/library/socket.html#socket.socket.sendall). – AndiDog Feb 01 '11 at 21:38

2 Answers2

1

In his comment on my question, Winston Ewert was correct. The socket.send should have read:

send_bufr = "PRIVMSG %s :Hello %s\r\n" %(self.channel, sender)
print(send_bufr)
self.sock.send(bytearray(send_bufr, "utf-8"))

A dumb mistake on my part to leave out the terminator. Thanks to everyone who helped.

Michael Smith
  • 1,847
  • 2
  • 19
  • 19
0

Try:

sock.setsockopt(socket.IPPROTO_TCP, socket.TCP_NODELAY, 1)

which should flush the buffer pretty much immediately.

Henry Finucane
  • 704
  • 3
  • 12