Question

I am doing a combination of Socket programming and pexpect in the same code. I have got it working but with a minor glitch. The select API waits for the specified 5 seconds in the first iteration. As soon as it received an input from the client it no longer waits for 5 seconds even though it is specified in the loop. In short after the first client server interaction takes place, select has no effect! I understand how to bypass this in C++ but I am comparatively new to Python and am unable to figure out the reason. I have attached the code below and is a pretty simple one.

#!/usr/bin/python
#Basic Functionailty: to create a process and to take inputs from client machines
#This input will be given to a background process which will display the user the parsed output
#using pexpect
import pexpect
import socket
import select

TCP_IP = '127.0.0.1'
TCP_PORT = 50050
BUFFER_SIZE = 1024

#spawning a pexpect process and printing everything before the prompt appears
child = pexpect.spawn('./pox.py')
child.expect ('POX>')
print child.before

#binding to a port number and acting as a server
server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server.bind((TCP_IP, TCP_PORT))
server.listen(1)
input = [server]

#loop infinitely and get input and serve it to the process
#in addition to which if the process shows some messages display
#it to the user
while 1:
  print 'Before select'
  inputready,outputready,exceptready = select.select(input,[],[],5)
  for s in inputready:
    if s == server:
      #if the input is from the server
      conn, addr = s.accept()
      print 'Connection address:', addr
      input.append(conn)
      data = conn.recv(BUFFER_SIZE)
      if not data: continue
      print "received data:", data
      child.sendline (data)

    else:
      #if a time out occurs check the pexpect if it has any debug messages
      i = child.expect ([pexpect.TIMEOUT, 'POX>'], timeout=1)
      print child.before
      if i == 0:
        print child.before
Was it helpful?

Solution

You've modified input:

input.append(conn)

(and then called conn.recv to get some data, which will block until there is some data or EOF, but presumably there was some and you got it).

Having done that, on the next trip through the loop, it's likely that there is receive data, or EOF, ready for input on conn. I assume you immediately call child.expect (because s == conn and hence s != server). I'd bet that at this point, conn is at EOF, so that returns immediately, having done nothing. conn is still open, and still in input, so every time you call select it returns right away telling you that you can read another EOF from conn.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top