Issue with writing simple TCP server in python

Question:

I am writing a is simple TCP server using python. when i type in "localhost:12001/HelloWorld.html" into my web browser it is meant to display "Hello world" from the html file saved in my directory.

When i run it, this is what is displayed in my web browser:

<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta http-equiv="Content-Style-Type" content="text/css">
  <title></title>
  <meta name="Generator" content="Cocoa HTML Writer">
  <meta name="CocoaVersion" content="2113.5">
  <style type="text/css">
    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 13.0px 'Helvetica Neue'; color: #000000; -webkit-text-stroke: #000000}
    span.s1 {font-kerning: none}
  </style>
</head>
<body>
<p class="p1"><span class="s1">Hello World !</span></p>
</body>
</html>

Here is my source code :

from socket import *

serverSocket = socket(AF_INET, SOCK_STREAM) 
serverPort = 12001
serverSocket.bind(('127.0.0.1', serverPort))
serverSocket.listen(1)

while True:

    print('Ready to serve...')
    connectionSocket, addr = serverSocket.accept()

    try:

        message = connectionSocket.recv(1024).decode()
        filename = message.split()[1]
        f = open(filename[1:])
        outputdata = f.read()
     
# #Send one HTTP header line into socket
        connectionSocket.send('HTTP/1.1 200 OKrnrn')
        
#Send the content of the requested file to the client
        for i in range(0, len(outputdata)):
            connectionSocket.send(outputdata[i])
        connectionSocket.close()
    except IOError:
    #Send response message for file not found
        print('404 Not Found')
        connectionSocket.send("""HTTP/1.0 404 Not Foundrn""".encode());

#Close client socket
        connectionSocket.close()

any help is appreciated , thanks

Asked By: el smooth

||

Answers:

  1. Don’t send your text one character at a time in a loop

Change this:

for i in range(0, len(outputdata)):
    connectionSocket.send(outputdata[i])

To this:

connectionSocket.send(outputdata)
  1. Encode all response strings as utf-8 bytes
outputdata = f.read().encode(encoding='utf-8')
  1. Add the Content-Length and Content-Type headers to response

So browser will know how to use this

connectionSocket.send('HTTP/1.1 200 OKrnContent-Length: %drnContent-Type: text/htmlrnrn'
                      .format(outputlength)
                      .encode(encoding='utf-8'))

Content-Length is a length of your data in bytes (outputdata)

Content-Type tells the browser how to interpret the response (text/html)

My working example of your code:

from socket import *

serverSocket = socket(AF_INET, SOCK_STREAM)
serverPort = 12001
serverSocket.bind(('127.0.0.1', serverPort))
serverSocket.listen(1)

while True:
    print('Ready to serve...')
    connectionSocket, addr = serverSocket.accept()
    
    try:
        message = connectionSocket.recv(1024).decode()
        filename = message.split()[1]
        f = open(filename[1:])
        outputdata = f.read().encode(encoding='utf-8')
        outputlength = len(outputdata)
        
        # #Send one HTTP header line into socket
        connectionSocket.send('HTTP/1.1 200 OKrnContent-Length: %drnContent-Type: text/htmlrnrn'
                              .format(outputlength)
                              .encode(encoding='utf-8'))
        
        # Send the content of the requested file to the client
        connectionSocket.send(outputdata)
        connectionSocket.close()
    except IOError:
        # Send response message for file not found
        print('404 Not Found')
        connectionSocket.send("""HTTP/1.0 404 Not Foundrn""".encode())
        
        # Close client socket
        connectionSocket.close()

Answered By: Mishin870
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.