Page 1 of 3 123 LastLast
Results 1 to 10 of 28

Thread: Beginner programming challenge #5

  1. #1
    Join Date
    May 2008
    Beans
    Hidden!

    Beginner programming challenge #5

    Beginners Programming Challenge #5

    It took me a little while to come up with a good idea. The first few I had were either boring or too hard.

    This one might teach you something new if you aren't already familiar- networking. You are going to write a server.

    Rules

    The server must accept client connections, and echo lines from each connection to every other connection. That is, if clients A, B, and C are connected and A send "Hello, world", this string should show up in B and C's windows.

    In a way, this is a simple kind of chat server.

    Extra features

    The more features you can give it, the better. Some suggestions:

    • A "login" sequence. Require clients to give themselves a name, and send this name along with messages that they send. Then you can tell who said what.
    • Following the first suggestion, send notifications to other clients when someone connects or disconnects.
    • Authentication- let names (or only some) require a password. Maybe even let that password be changed.


    Going above and beyond this list is encouraged- anything you can think of.

    Hints

    You have to be able to listen to every client connection you have at once. Polling is rather unoptimal in this situation. Threads are one possibility, but this does not scale well to more than a few clients. Also, it requires locking, which makes it more complicated. The best way to multiplex connections is to be asyncronous in the first place.

    For that, the common solution is to use select(), which waits for one of a set of sockets to have available data.

    For Python programmers, I direct you to the socket and select modules in the standard library. The examples in the documentation should help you along.

    An alternative option for Python is to use the Twisted networking framework- if you can take the time to learn how to use it (it's not that complicated, it may be simpler than the first option of rolling your own socket code), it will serve you well in many ways.

  2. #2
    Join Date
    Jan 2009
    Beans
    42

    Re: Beginner programming challenge #5

    Sounds interesting, so we need to write a client program and a server program as well that can talk with more than 1 client program at a time?

  3. #3
    Join Date
    May 2008
    Beans
    Hidden!

    Re: Beginner programming challenge #5

    Quote Originally Posted by Coldhearth View Post
    Sounds interesting, so we need to write a client program and a server program as well ...
    Just the server. For a client, all you really need is netcat (a socket utility) to send data directly to the socket. But if your server had enough features, a specialized client wouldn't be too bad of an idea.

    Oh, and by the way, some clients will send "\n" to mark the end of the line, and others will send "\r\n"... the latter is more typical on the internet, but why be specific?

    (Or you could just assume the former, it's easier.)

    ... that can talk with more than 1 client program at a time?
    They all have to.

  4. #4
    Join Date
    Jan 2009
    Beans
    42

    Re: Beginner programming challenge #5

    Hmm interesting, although I wouldn't know where to start...
    Can you maybe point me in the right direction? (I have never done networking before)

  5. #5
    Join Date
    Feb 2009
    Beans
    789
    Distro
    Ubuntu 10.04 Lucid Lynx

    Re: Beginner programming challenge #5

    Quote Originally Posted by Coldhearth View Post
    Hmm interesting, although I wouldn't know where to start...
    Can you maybe point me in the right direction? (I have never done networking before)
    I must say I felt it to be complicated for a beginners challenge. After all, you need to know about localhost, ports, sockets and let's forget threads

  6. #6
    Join Date
    May 2008
    Beans
    Hidden!

    Re: Beginner programming challenge #5

    Quote Originally Posted by Coldhearth View Post
    Hmm interesting, although I wouldn't know where to start...
    Can you maybe point me in the right direction? (I have never done networking before)
    Assuming Python: The documentation for the socket module should show you how to set up a server socket and listen for connections.

    After that, it becomes a problem of polling your clients for data to read.

    I must say I felt it to be complicated for a beginners challenge. After all, you need to know about localhost, ports, sockets and let's forget threads
    I tried not to let it get too complicated, but you don't need threads.

    I'm hoping somebody uses Twisted, because it's wonderful for Python networking.

    How to write servers in Twisted (should show you how the API in general works)
    Twisted tutorial

  7. #7
    Join Date
    Jan 2008
    Beans
    1,532

    Re: Beginner programming challenge #5

    Quote Originally Posted by simeon87 View Post
    I must say I felt it to be complicated for a beginners challenge. After all, you need to know about localhost, ports, sockets and let's forget threads
    Even in C, you can do this in a few hundred lines of code (less if you want to skip some features). And you don't need threads if you have the select function like C and, apparently, Python.

  8. #8
    Join Date
    Jul 2008
    Beans
    1,706

    Re: Beginner programming challenge #5

    points off for using POE or twisted? (i am curious even though i am using erlang)

  9. #9
    Join Date
    May 2008
    Beans
    Hidden!

    Re: Beginner programming challenge #5

    Quote Originally Posted by jimi_hendrix View Post
    points off for using POE or twisted? (i am curious even though i am using erlang)
    No.

  10. #10
    Join Date
    Oct 2008
    Location
    $HOME
    Beans
    112
    Distro
    Ubuntu 11.10 Oneiric Ocelot

    Re: Beginner programming challenge #5

    Do I get points for being the first answer?
    The Server:
    PHP Code:
    #!/usr/bin/env python
    import socketselect

    HOST 
    'localhost'
    PORT 9001
    server 
    socket.socket(socket.AF_INETsocket.SOCK_STREAM)
    server.bind((HOSTPORT))
    server.listen(3)
    connections = [server]

    def send(connectionmessage):
        
    connection.send(message '\r\n')

    while 
    True:
        
    ready_connections select.select(connections, [], [])[0]
        for 
    connection in ready_connections:
            if 
    connection is server:
                
    connectaddress server.accept()
                
    connections.append(connect)
                print 
    'Connected: ' address[0]
                for 
    con in connections:
                    if 
    con is not server and con is not connect:
                        
    send(conaddress[0] + ' JOIN')
            else:
                
    message connection.recv(512)
                if 
    message:
                    
    address connection.getsockname()[0]
                    print 
    'Recieved From ' connection.getsockname()[0] + ' :' message
                    
    for con in connections:
                        if 
    con is not server and con is not connection:
                            
    send(conaddress ' MSG :' message)
                else:
                    
    address connection.getsockname()[0]
                    print 
    'Disconnected: ' address
                    connection
    .close()
                    
    connections.remove(connection)
                    for 
    con in connections:
                        if 
    con is not server and con is not connection:
                            
    send(conaddress ' QUIT'
    And The Client:
    PHP Code:
    #!/usr/bin/env python
    import socketthreading

    HOST 
    'localhost'
    PORT 9001
    client 
    socket.socket(socket.AF_INETsocket.SOCK_STREAM)
    client.connect((HOSTPORT))

    def listen():
        while 
    True:
            
    data client.recv(512)[:-2].split()
            
    who data[0]
            
    command data[1]
            
    args data[2:]
            if 
    command == 'MSG':
                print 
    who ': ' ' '.join(args)[1:]
            if 
    command == 'JOIN':
                print 
    '--> ' who ' has joined'
            
    if command == 'QUIT':
                print 
    '<-- ' who ' has quit'

    def send():
        while 
    True:
            try:
                
    message raw_input('')
            
    except KeyboardInterrupt:
                
    message 'quit'
                
    print
            if 
    message.lower() == 'quit':
                
    client.close()
                exit()
            
    client.send(message '\r\n')

    thread1 threading.Thread(target listen)
    thread2 threading.Thread(target send)
    thread1.start()
    thread2.run() 
    EDIT: Ooops, forgot something. It'll work, but...
    Last edited by bgs100; June 3rd, 2009 at 02:41 AM.
    $(fortune)
    In a world without walls and fences, who needs windows and gates?

Page 1 of 3 123 LastLast

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •