1

I'm using Python to write a simple script that will connect to a host/port using a socket. I know sockets can only be used once which is why I'm not closing the socket at all but when I connect to localhost on port 80 and try a simple command like GET / it works the first time but the second time I execute GET / or any other HTTP command, it doesn't print the output. Here is what I have


import socket
size = 1024
host = 'localhost'
port = 80
def connectsocket(userHost, userPort):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) #TCP socket
    s.connect((userHost, userPort))
    while(1):
        input = raw_input("Command: ")
        s.send(input + '\r\n\r\n') #Send command
        r = s.recv(size) #Recieve output
        print(r)
connectsocket(host, port)

I'd assume this would work but here is a sample output:


amartin@homebox:~$ python socketconn.py
Command: GET /
[BUNCH OF HTML CODE]
Command: GET /

Command:

As you can see it works for the first GET / but not for the second. How can I fix this?

2
  • Where did you get that sockets can only be used one? You can re-use sockets. Commented Mar 8, 2011 at 1:47
  • I mean if you close a socket you can't use that same socket. Commented Mar 8, 2011 at 1:52

2 Answers 2

1

Given information from the comments on @samplebias' answer, I think this is similar to what you're looking to accomplish:

import errno
import socket

size = 1024
host = 'localhost'
port = 80


def connectsocket(userHost, userPort):

    while(1):
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  # TCP socket
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.connect((userHost, userPort))

        command = raw_input("Command: ")

        s.send(command + '\r\n\r\n')  # Send command
        response = s.recv(size)  # Recieve output
        print response

        try:
            s.shutdown(socket.SHUT_RDWR)
        except socket.error, exc:
            # Depending on the platform, shutting down one half of the
            # connection can also close the opposite half
            if exc.errno != errno.ENOTCONN:
                raise

        s.close()


connectsocket(host, port)

It probably makes sense for you to check out the Twisted library as well. You can also check out this book: Foundations of Python Network Programming.

There's also a good socket tutorial on the python documentation website that can be of assistance. Last, but not least, there's a slightly more comprehensive tutorial that I found on Google which looks great for beginners.

HTH.

Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for all that info I'll be checking out those links. Also, wouldn't this code keep opening a new socket with the loop? Wouldn't that give you a Tranport endpoint is already connected error?
No, because you've shut down the port and closed it towards the end. The socket is no longer connected once the shutdown()/close() methods are executed.
I see. Does the s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) need to be in the while loop?
0

You need to tell the server to keep the TCP connection open and expect more requests:

headers = 'Connection: keep-alive\r\n'
s.send(input + '\r\n' + headers + '\r\n')

Also, try specifying the HTTP version:

python socketconn.py 
Command: GET / HTTP/1.1

7 Comments

Will this work for all services though? Other than just http? EDIT: Just tried it and it seems to not work. I've tried playing around with the header but no luck.
The above is HTTP-specific. For example if you want to open a socket to an FTP server the protocol is completely different. Are you learning or you are you trying to implement a tool of some kind? If the latter, you'll want to use an existing library to handle the HTTP protocol and socket comms for you as the details can be quite tricky. The urllib2 module is one example.
Well I'm writing a simple tool. And I want it to be universal so it will work with just about any port you connect to.
If you want to build a generic socket poller which lets you interact with sockets using line-oriented protocols, that sounds doable. Sort of like telnet with a higher-level command set.
If that's the case, then you need to re-word your question.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.