I have to create a web server in Python. Below is the code I am working on. When i execute it, I initially get no error and it prints "Ready to serve.." , but after opening a browser and running http://10.1.10.187:50997/HelloWorld.html (HelloWorld is an html file in the same folder as my python code, while 10.1.10.187 is my IP address and 50997) is the server port), I get a TypeError saying 'a bytes like object is required and not str". please help me in resolving this and kindly let me know if any other modifications are required.
#Import socket module
from socket import *
#Create a TCP server socket
#(AF_INET is used for IPv4 protocols)
#(SOCK_STREAM is used for TCP)
# Assign a port number
serverPort = 50997
serverSocket = socket(AF_INET, SOCK_STREAM)
#serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#print ("hostname is: "), gethostname()
#print ("hostname is: "), socket.gethostname()
# Bind the socket to server address and server port
serverSocket.bind(("", serverPort))
# Listen to at most 1 connection at a time
serverSocket.listen(1)
# Server should be up and running and listening to the incoming connections
while True:
print ("Ready to serve...")
# Set up a new connection from the client
connectionSocket, addr = serverSocket.accept()
try:
# Receives the request message from the client
message = connectionSocket.recv(1024)
print ("Message is: "), message
filename = message.split()[1]
print ("File name is: "), filename
f = open(filename[1:])
outputdata = f.read()
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i])
connectionSocket.send("\r\n")
# Close the client connection socket
connectionSocket.close()
except IOError:
# Send HTTP response message for file not found
connectionSocket.send("HTTP/1.1 404 Not Found\r\n\r\n")
connectionSocket.send("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n")
# Close the client connection socket
connectionSocket.close()
serverSocket.close()
The error I am exacly getting-
Ready to serve...
Message is:
File name is:
Traceback (most recent call last):
File "intro.py", line 56, in <module>
connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n")
TypeError: a bytes-like object is required, not 'str'
You need to convert the string you are sending into bytes, using a text format. A good text format to use is UTF-8. You can implement this conversion like so:
bytes(string_to_convert, 'UTF-8')
or, in the context of your code:
connectionSocket.send(bytes("HTTP/1.1 404 Not Found\r\n\r\n","UTF-8"))
connectionSocket.send(bytes("<html><head></head><body><h1>404 Not Found</h1></body></html>\r\n","UTF-8"))`
Related
As I wrote on title, I have already successfully connected the server and client.
But the client can't display the HTML file.
I checked file path and send function. But can't find any fault.
When running the code, the code runs normally until connectionSocket.close().
But browser can't display the HTML file, just blank.
So, I checked the details and I found that connectionSocket.send(outputdata[i].encode()) send values, 1 or 3.
I don't know the reason but I'm sure that that is the cause.
Please give me your insight.
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
TCPPort = 8000
BufferSize = 1024
serverSocket.bind((host, TCPPort))
serverSocket.listen(1)
while True:
# Establish the connection
print('Ready to serve...')
(connectionSocket,addr) = serverSocket.accept()
print('connectionSocket is:',connectionSocket)
try:
message = connectionSocket.recv(BufferSize)
print('message is:',message)
#filename = message.split()[1]
#print('filename is:', filename)
f = open('\HTML.html','r',encoding='UTF-8')
outputdata = f.read()
# Send one HTTP header line into socket
connectionSocket.send('HTTP/1.1 200 OK\r\n'.encode('UTF-8'))
# Send the content of the requested file to the client
for i in range(0,len(outputdata)):
connectionSocket.send(outputdata[i].encode())
connectionSocket.close()
except IOError:
connectionSocket.send('HTTP/1.1 404 Not Found'.encode('UTF-8'))
connectionSocket.send("<html><head></head><body><h1>404 Not Found</h1></body></html> ".encode('UTF-8'))
# Close client socket
connectionSocket.close()
serverSocket.close()
You need to make your server to respond by the HTTP protocol. In HTTP there are 2 newlines between headers and body and you need to send both together:
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
TCPPort = 8000
BufferSize = 1024
serverSocket.bind(('127.0.0.1', TCPPort))
serverSocket.listen(1)
while True:
# Establish the connection
print('Ready to serve...')
(connectionSocket, addr) = serverSocket.accept()
print('connectionSocket is:', connectionSocket)
try:
message = connectionSocket.recv(BufferSize)
print('message is:', message)
#filename = message.split()[1]
#print('filename is:', filename)
#f = open('\HTML.html','r',encoding='UTF-8')
outputdata = "<html><body>foo</body></html>"
# Send one HTTP header line into socket
response = 'HTTP/1.1 200 OK\nConnection: close\n\n' + outputdata
connectionSocket.send(response.decode())
# Send the content of the requested file to the client
connectionSocket.close()
except IOError:
connectionSocket.send('HTTP/1.1 404 Not Found'.encode('UTF-8'))
connectionSocket.send(
"<html><head></head><body><h1>404 Not Found</h1></body></html> ".
encode('UTF-8')
)
# Close client socket
connectionSocket.close()
serverSocket.close()
Test, using: curl -X GET http://localhost:8000
Out:
<html><body>foo</body></html>
So, i am trying to create a simple server on python and trying to access a html file in the same directory through it, but as the output i keep on getting ready to serve...
output
EDIT:
Put an HTML file (e.g., HelloWorld.html) in the same directory that the server is in. Run the server program. Determine the IP address of the host that is running the server (e.g., 128.238.251.26). From another host, open a browser and provide the corresponding URL. For example:
http://128.238.251.26:6789/HelloWorld.html
‘HelloWorld.html’ is the name of the file you placed in the server directory. Note also the use of the port number after the colon. You need to replace this port number with whatever port you have used in the server code. In the above example, we have used the port number 6789. The browser should then display the contents of HelloWorld.html. If you omit ":6789", the browser will assume port 80 and you will get the web page from the server only if your server is listening at port 80.
Then try to get a file that is not present at the server. You should get a “404 Not Found” message.
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
serverSocket.bind(('', 12006))
serverSocket.listen(1)
while True:
print 'Ready to serve...'
#Establish the connection
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.read()
f.close()
#Send one HTTP header line into socket
connectionSocket.send('HTTP/1.0 200 OK\r\n\r\n')
#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
connectionSocket.send('404 Not Found')
#Close client socket
connectionSocket.close()
serverSocket.close()
Your output is a standart output, that used through print function. you should to make a request to your server and you'll get the correct output
If your server on your local machine, you should use localhost address; if not, you should use your server ip. Also you should to specify a port. 12006 in your case. localhost:12006 as an example
Also socket.send method requires a byte-like object. not string
If it's only a string literal, you should to add a b character before the first quotation mark
Example:
connectionSocket.send(b'HTTP/1.0 200 OK\r\n\r\n')
If it is a string object, you should to encode it:
connectionSocket.send(outputdata[i].encode())
Check out the documentation
Simple client - server app.
#Server use decode
import socket
s = socket.socket()
host = socket.gethostname()
port = 12345
s.bind((host,port))
s.listen(5)
while True:
c,addr = s.accept()
print("Got connection from " + str(addr))
ret_val = s.send("Thank you".encode('utf-8'))
print ("ret_val={}".format(ret_val))
c.close()
Client:
#client use decode
from socket import gethostname, socket
serSocket = socket()
server = gethostname()
port = 12345
serSocket.connect((server, port))
data = serSocket.recv(1024)
msg = data.decode('utf-8')
print("Returned Msg from server: <{}>".format(msg))
serSocket.close()
when the server tries to send the following exception occurred
Traceback (most recent call last):
Got connection from ('192.168.177.1', 49755)
File "C:/Users/Oren/PycharmProjects/CientServer/ServerSide/Server2.py", line 16, in <module>
ret_val = s.send("Thank you".encode('utf-8'))
OSError: [WinError 10057] A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied
Process finished with exit code 1
As can be seen the client connects the server successfully.
But send fails.
What is the problem?
The problem is that you are sending on the listening socket, not on the connected socket. connect returns a new socket which is the one you must use for data transfer. The listening socket can never be used for sending or receiving data.
Change the send to this and your program will work fine:
ret_val = c.send("Thank you".encode('utf-8'))
(Note c.send, not s.send)
It's my client:
#CLIENT
import socket
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
i=0
while True:
conne.connect ( ('127.0.0.1', 3001) )
if i==0:
conne.send(b"test")
i+=1
data = conne.recv(1024)
#print(data)
if data.decode("utf-8")=="0":
name = input("Write your name:\n")
conne.send(bytes(name, "utf-8"))
else:
text = input("Write text:\n")
conne.send(bytes(text, "utf-8"))
conne.close()
It's my server:
#SERVER
import socket
counter=0
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.bind(('', 3001))
sock.listen(10)
while True:
conn, addr = sock.accept()
data = conn.recv(1024)
if len(data.decode("utf-8"))>0:
if counter==0:
conn.send(b"0")
counter+=1
else:
conn.send(b"1")
counter+=1
else:
break
print("Zero")
conn.send("Slava")
conn.close()
))
After starting Client.py i get this error:
Traceback (most recent call last): File "client.py", line 10, in
conne.connect ( ('127.0.0.1', 3001) ) OSError: [Errno 9] Bad file descriptor
Problem will be created just after first input.
This program - chat. Server is waiting for messages. Client is sending.
There are a number of problems with the code, however, to address the one related to the traceback, a socket can not be reused once the connection is closed, i.e. you can not call socket.connect() on a closed socket. Instead you need to create a new socket each time, so move the socket creation code into the loop:
import socket
i=0
while True:
conne = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
conne.connect(('127.0.0.1', 3001))
...
Setting socket option SO_BROADCAST on a stream socket has no affect so, unless you actually intended to use datagrams (UDP connection), you should remove the call to setsockopt().
At least one other problem is that the server closes the connection before the client sends the user's name to it. Probably there are other problems that you will find while debugging your code.
Check if 3001 port is still open.
You have given 'while True:' in the client script. Are you trying to connect to the server many times in an infinite loop?
Currently doing an assignment in which we are programming sockets in python and thus creating a web server when the webserver.py code is executed.The code should then display HTTP headers and other information when you access a file(test.html)from the web server. Now my code works (or I'd like to believe so) and I have created a test.html file and the question goes on to say that I should place the test.html file in the same directory as the web server, where exactly is that on my local machine? I placed the test.html in the same folder as webserver.py in the python's root directory and proceeded to 127.0.0.1:1336/test.html to test my code but it doesn't work, where exactly on my machine is the webserver directory in which I should place test.html? Is it that I have to use wamp/xamp and place the test.html in there?
N.B 1336 is the port I specified in the code to connect to.
#import socket module
from socket import *
serverSocket = socket(AF_INET, SOCK_STREAM)
#Prepare a sever socket
serverPort = 1336
serverSocket.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
serverSocket.bind(('', serverPort)) #set up socket connection
serverSocket.listen(1) #tells the server to try a maximum of one connect request before ending connection
while True:
#Establish the connection
print 'Ready to serve...'
connectionSocket, addr = serverSocket.accept()
print 'connected to port',serverPort
try:
message = connectionSocket.recv(1024) #Makes it so that you can recieve message from client
filename = message.split()[1]
f = open(filename[1:])
outputdata = f.open(filename[1:])
#Send one HTTP header line into socket2
#Fill in start
connectionSocket.send('HTTP/1.0 200 OK\r\n')
#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 Error : File Not Found.'
#Close client socket
connectionSocket.close()
serverSocket.close()
First of all, you shouldn't use the socket module to make a HTTP server. I recommend using the http.ser ver module, and change the working directory to where the html files are. Lets say i had test.html in C:\User\Desktop.
An example:
from http.server import HTTPServer, CGIHTTPRequestHandler
import os
os.chdir("C:/User/Desktop")
address = ("", 1336)
httpserver = HTTPServer(address,, CGIHTTPRequestHandler)
httpserver.serve_forever()
Then you can access it by 127.0.0.1:1336/test.html
If this isn't the answer you are looking for, please add the webserver.py to the question.