views:

449

answers:

2

Hello!

How can I make a simple server(simple as in accepting a connection and print to terminal whatever is received) accept connection from multiple ports or a port range?

Do I have to use multiple threads, one for each bind call. Or is there another solution?

The simple server can look something like this.

def server():
import sys, os, socket

port = 11116
host = ''
backlog = 5 # Number of clients on wait.
buf_size = 1024

try:
 listening_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 listening_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 
 listening_socket.bind((host, port)) 
 listening_socket.listen(backlog)
except socket.error, (value, message):
 if listening_socket:
  listening_socket.close()
 print 'Could not open socket: ' + message
 sys.exit(1)

while True:
 accepted_socket, adress = listening_socket.accept()

 data = accepted_socket.recv(buf_size)
 if data:
  accepted_socket.send('Hello, and goodbye.')
 accepted_socket.close()

server()

EDIT: This is an example of how it can be done. Thanks everyone.

import socket, select

def server():
import sys, os, socket

port_wan = 11111
port_mob = 11112
port_sat = 11113

sock_lst = []
host = ''
backlog = 5 # Number of clients on wait.
buf_size = 1024

try:
 for item in port_wan, port_mob, port_sat:
  sock_lst.append(socket.socket(socket.AF_INET, socket.SOCK_STREAM))
  sock_lst[-1].setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 
  sock_lst[-1].bind((host, item)) 
  sock_lst[-1].listen(backlog)
except socket.error, (value, message):
 if sock_lst[-1]:
  sock_lst[-1].close()
  sock_lst = sock_lst[:-1]
 print 'Could not open socket: ' + message
 sys.exit(1)

while True:
 read, write, error = select.select(sock_lst,[],[])

 for r in read:
  for item in sock_lst:
   if r == item:
    accepted_socket, adress = item.accept()

    print 'We have a connection with ', adress
    data = accepted_socket.recv(buf_size)
    if data:
     print data
     accepted_socket.send('Hello, and goodbye.')
    accepted_socket.close()

server()
+3  A: 

I'm not a python guy, but the function you are interested in is "select". This will allow you to watch multiple sockets and breaks out when activity occurs on any one of them.

Here's a python example that uses select.

Eric Petroelje
I am a Python guy, and you need select: http://docs.python.org/library/select.html
S.Lott
Thanks. Se my original post for an example code
Orjanp
+1  A: 

If you really wanted to be lazy (from a programmer standpoint, not an evaluation standpoint), you could set a timeout on your blocking read and just loop through all your sockets; if a timeout occurs, there wasn't any data available. Functionally, this is similar to what the select is doing, but it is taking that control away from the OS and putting it in your application.

Of course, this implies that as your sleep time gets smaller, your program will approach 100% CPU usage, so you wouldn't use it on a production app. It's fine for a toy though.

It would go something like this: (not tested)

def server():
    import sys, os, socket

    port = 11116
    host = ''
    backlog = 5 # Number of clients on wait.
    buf_size = 1024
    NUM_SOCKETS = 10
    START_PORT = 2000

    try:
            socket.setdefaulttimeout(0.5) # raise a socket.timeout error after a half second
            listening_sockets = []
            for i in range(NUM_SOCKETS):
                listening_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
                listening_socket.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) 
                listening_socket.bind((host, START_PORT + i)) 
                listening_socket.listen(backlog)
                listening_sockets.append(listening_socket)
    except socket.error, (value, message):
            if listening_socket:
                    listening_socket.close()
            print 'Could not open socket: ' + message
            sys.exit(1)

    while True:
            for sock in listening_sockets:
                try:
                    accepted_socket, adress = sock_socket.accept()

                    data = sock.recv(buf_size)
                    if data:
                            sock_socket.send('Hello, and goodbye.')
                    sock.close()
                except socket.timeout:
                    pass

    server()
Mark Rushakoff
Why implement your own select? Isn't the built-in select module simpler than this?
S.Lott
Thanks. I guess since the select uses less CPU. I went for that solution.
Orjanp
I vaguely recall it *not* being simpler. But now that I think about it a little more, there's a pretty good chance that I was working in C, not Python, when I was doing that :(
Mark Rushakoff