Right now in my code, the index.html file is read on the server and then sent from the server to the client connection. I need to make it so that I have a separate client application that formulates the HTTP request and sends it to the server to send HTTP response. Just not quite sure how to do that. I have an echo-client.py file but it doesn't work at the moment. The server application works and displays the index.html at localhost:14000 with the server.py code below:
server.py
"""
Implements a simple HTTP/1.0 Server
"""
import socket
# Define socket host and port
SERVER_HOST = '127.0.0.1'
SERVER_PORT = 14000
# Create socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
server_socket.bind((SERVER_HOST, SERVER_PORT))
server_socket.listen(1)
print('Listening on port %s ...' % SERVER_PORT)
while True:
# Wait for client connections
client_connection, client_address = server_socket.accept()
# Get the content of index.html
# HTTP Request
fin = open('index.html')
content = fin.read()
fin.close()
# Send HTTP response
response = 'HTTP/1.0 200 OK\n\n' + content
client_connection.sendall(response.encode())
# client_connection.close()
# Close socket
server_socket.close()
I've tried configuring the client.py application like this but it says:
File "/Users/jamesmeegan/Desktop/COSC 350 Data Comm/Problem3_HW3/echo-client.py", line 33, in <module>
s.sendall((content))
TypeError: a bytes-like object is required, not 'str'
and I'm not sure how I would even receive it on the server end.
client.py
# echo-client.py
import socket
HOST = "127.0.0.1" # The server's hostname or IP address
PORT = 14000 # The port used by the server
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.connect((HOST, PORT))
fin = open('index.html')
content = fin.read()
fin.close()
s.sendall((content))
data = s.recv(1024)
print(f"Received {data!r}")
Related
I am building a server to send data to the client in Python. I would like to continuously send the time until the client closes the connection. So far, I have done :
For the server:
import socket
from datetime import datetime
# take the server name and port name
host = 'local host'
port = 5001
# create a socket at server side
# using TCP / IP protocol
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
# bind the socket with server
# and port number
s.bind(('', port))
# allow maximum 1 connection to
# the socket
s.listen(1)
# wait till a client accept
# connection
c, addr = s.accept()
# display client address
print("CONNECTION FROM:", str(addr))
dateTimeObj = str(datetime.now())
print(dateTimeObj)
c.send(dateTimeObj.encode())
# disconnect the server
c.close()
For the client:
import socket
# take the server name and port name
host = 'local host'
port = 5001
# create a socket at client side
# using TCP / IP protocol
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
# connect it to server and port
# number on local computer.
s.connect(('127.0.0.1', port))
# receive message string from
# server, at a time 1024 B
msg = s.recv(1024)
# repeat as long as message
# string are not empty
while msg:
print('Received date :' + msg.decode())
msg = s.recv(1024)
# disconnect the client
s.close()
How can I modify the server to continously send the current date? At the moment, the server is just sending one date and closing the connection.
you need to use While True loop.
import socket
from datetime import datetime
# take the server name and port name
host = 'local host'
port = 5001
# create a socket at server side
# using TCP / IP protocol
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
# bind the socket with server
# and port number
s.bind(('', port))
# allow maximum 1 connection to
# the socket
s.listen(1)
# wait till a client accept
# connection
while True:
c, addr = s.accept()
# display client address
print("CONNECTION FROM:", str(addr))
dateTimeObj = str(datetime.now())
print(dateTimeObj)
c.send(dateTimeObj.encode())
# disconnect the server
c.close()
client:
import socket
# take the server name and port name
host = 'local host'
port = 5001
# create a socket at client side
# using TCP / IP protocol
s = socket.socket(socket.AF_INET,
socket.SOCK_STREAM)
# connect it to server and port
# number on local computer.
s.connect(('127.0.0.1', port))
# receive message string from
# server, at a time 1024 B
while True:
msg = s.recv(1024)
# repeat as long as message
# string are not empty
while msg:
print('Received date :' + msg.decode())
msg = s.recv(1024)
# disconnect the client
s.close()
I guess Python automatically send a close sign when shuts down(ctr+c) the client.
python tcp server
import socket
HOST = '127.0.0.1' # Standard loopback interface address (localhost)
PORT = 12345 # Port to listen on (non-privileged ports are > 1023)
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind((HOST, PORT))
s.listen()
conn, addr = s.accept()
with conn:
print('Connected by', addr)
while True:
data = conn.recv(1024)
#if not data:break
conn.sendall(data)
print(data)
python tcp client
import socket
HOST = '127.0.0.1' # The server's hostname or IP address
PORT = 12345 # The port used by the server
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((HOST, PORT))
s.sendall(b'Hello, world')
data = s.recv(1024)
print('Received', data)
#s.close()
When executing this code,
the server continues to receive null data (maybe close sign) by the client that ended without closing.
Connected by ('127.0.0.1', 55305)
b'Hello, world'
b''
b''
b''
b''
b''
...
This error occurs when run node.js client and shutdown(ctr+c) without close sign.
The python tcp server occurs error but not print null.
node.js tcp client
const Net = require('net');
const client = new Net.Socket();
client.setEncoding('utf8');
client.connect({ port: 12345, host: '127.0.0.1' })
client.write('Hello, world');
/*client.end()*/
Connected by ('127.0.0.1', 56685)
b'Hello, world'
Traceback (most recent call last):
File "C:/.../server.py", line 13, in <module>
data = conn.recv(1024)
ConnectionResetError: [WinError 10054]An existing connection was forcibly closed by the remote host
I know that the server and the client need to send and receive the exit sign,
but I wonder why the Python client automatically sends the close sign when it is closed.
Where can I get information about this?
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>
I'm a beginner compsci student and I'm trying to code a simple server in python that takes a .HTML page stored in the same directory and sends it to a client on the same network using a TCP connection.
This is my code:
from socket import *
serverPort = 8000
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
serverSocket.bind(('', serverPort)) # binds socket to port 8000
serverSocket.listen(1) # waiting for client to initiate connection
while True:
# Establish the connection
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:].decode())
outputdata = f.read()
# Send one HTTP header line into socket
http_response = 'HTTP/1.1 200 OK\n'
connectionSocket.send(http_response.encode())
# Send the content of the requested file to the client
for i in range(0, len(outputdata)):
connectionSocket.send(outputdata[i].encode())
connectionSocket.send("\r\n".encode())
connectionSocket.close()
except IOError:
connectionSocket.send("\r\n".encode())
# DO LATER
serverSocket.close()
sys.exit()
And this is my simple html page:
<!DOCTYPE html>
<html>
<body>
<h1>My First Web Page</h1>
<p>You have successfully accessed the Web Server</p>
</body>
</html>
So far whenever I run my server and direct my browser to it, I only get the following served to me:
<p>You have successfully accessed the Web Server</p>
Along with the body and html tags after this. Checking the page source there's no header.
I ran Wireshark while trying to access my server and indeed it seems like I'm only sending through "You have successfully accessed the Web server" and onwards. This is despite the fact a print function shows I am definitely sending all the data in the file through the TCP connection.
Does anyone know what the issue is?
After sending the protocol answer and headers, the actual response comes after two \r\n sequences.
Use this fixed code:
from socket import *
serverPort = 8000
serverSocket = socket(AF_INET, SOCK_STREAM)
# Prepare a sever socket
serverSocket.bind(('', serverPort)) # binds socket to port 8000
serverSocket.listen(1) # waiting for client to initiate connection
while True:
# Establish the connection
print('Ready to serve...')
connectionSocket, addr = serverSocket.accept()
try:
message = connectionSocket.recv(1024)
filename = message.split()[1]
f = open(filename[1:].decode())
outputdata = f.read()
# Send one HTTP header line into socket
http_response = 'HTTP/1.1 200 OK\n'
connectionSocket.send(http_response.encode())
connectionSocket.send("\r\n".encode())
connectionSocket.send("\r\n".encode())
# 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:
# DO LATER
serverSocket.close()
sys.exit()
I would use the http.server library
import http.server
import socketserver
PORT = 8080
Handler = http.server.SimpleHTTPRequestHandler
with socketserver.TCPServer(("", PORT), Handler) as httpd:
httpd.serve_forever()
source: https://www.afternerd.com/blog/python-http-server/
I'm new to python programming. I want to create a simple TCP server working with an esp32. The idea of this is to send command data = '{\"accel\",\"gyro\",\"time\":1}' to esp32 via socket and then wait around 10ms for reply from esp32. I tried many examples but nothing works. ESP32 gets my message from this program but I can't receive message from esp32.
import socket
# bind all IP address
HOST = '192.168.137.93'
# Listen on Port
PORT = 56606
#Size of receive buffer
localhost=('0.0.0.0', 56606)
BUFFER_SIZE = 1024
# Create a TCP/IP socket
data = '{\"accel\",\"gyro\",\"time\":1}'
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Bind the socket to the host and port
s.connect((HOST, PORT))
# send data to server
s.send(bytearray(data, 'utf-8'))
s.serve_forever()
print('Listen for incoming connections')
sock.listen(1)
while True:
client, addr = s.accept()
while True:
content = client.recv(1024)
if len(content) ==0:
break
else:
print(content)
print("Closing connection")
client.close()
I tried more and tried to use other code(see below). Now I get message back but on other port(I can track it by wireshark)
import socket
# Ip of local host
HOST = '192.168.137.93'
# Connect to Port
PORT = 56606
#Size of send buffer
BUFFER_SIZE = 4096
# data to sent to server
message = '{\"accel\",\"gyro\",\"time\":1}'
# Create a TCP/IP socket
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
# Connect to server
s.connect((HOST, PORT))
# send data to server
s.send(bytearray(message, 'utf-8'))
# Receive response from server
data = ""
while len(data) < len(message):
data = s.recv(BUFFER_SIZE)
# Close connection
print ('Server to Client: ' , data)
s.close()
I don't use both of these codes together.
Any hints?