0%

ToyWebServer

Distributed System Programming Assignment

telnet

  • older and unsafer than ssh
  • by default, disabled by Windows
1
telnet google.com 80
1
GET / HTTP/1.1

Single-threaded Python Web Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
"""
Implements a simple HTTP/1.0 Server
"""

import os
import socket

#Get current directory
currentPath = os.getcwd().replace('\\','/')

def handle_request(request):
"""Handles the HTTP request."""

headers = request.split('\n')
filename = headers[0].split()[1]
if filename == '/':
filename = '/index.html'

try:
fin = open(currentPath + filename)
content = fin.read()
fin.close()

response = 'HTTP/1.0 200 OK\n\n' + content
except FileNotFoundError:
response = 'HTTP/1.0 404 NOT FOUND\n\nFile Not Found'

return response


# Define socket host and port
SERVER_HOST = '0.0.0.0'
SERVER_PORT = 8080

# 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 client request
request = client_connection.recv(1024).decode()
print(request)

# Return an HTTP response
response = handle_request(request)
client_connection.sendall(response.encode())

# Close connection
client_connection.close()

# Close socket
server_socket.close()

Multi-threaded Python Web Server

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import socket
import threading
import os

#Get current directory
currentPath = os.getcwd().replace('\\','/')
# 多线程服务器

def handle_conn(sock, address):
print("deal with connection ....")
t = threading.Thread(target=process_conn, args=(sock, address))
t.start()


def process_conn(sock, address):
print(threading.current_thread())

while True: # 多次为一个客户端服务
recv_data = sock.recv(1024)
# 如果 recv 解堵塞,客户端有两种方式 1. 发送了数据 2. 关闭了连接
if recv_data:
# 回送数据到客户端
# 最好使用 sendall

request=recv_data.decode()
print(request)

headers = request.split('\n')
filename = headers[0].split()[1]


if filename == '/':
filename = '/index.html'

try:
fin = open(currentPath+filename)
content = fin.read()
fin.close()

response = 'HTTP/1.0 200 OK\n\n' + content
except FileNotFoundError:
response = 'HTTP/1.0 404 NOT FOUND\n\nFile Not Found'

# Return an HTTP response
sock.sendall(response.encode())
else:
break
# 5. close socket
print("close socket..")
sock.close()


def main():
# 1. create socket
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. bind local information
tcp_server_socket.bind(("127.0.0.1", 8888))
# 3.
tcp_server_socket.listen()
# 4. accept connection from client
# 类似你在等待别人的电话到来
# 元组解包
while True:
print(threading.current_thread())
print("waitting ........")
new_client_socket, client_addr = tcp_server_socket.accept()
handle_conn(new_client_socket, client_addr)


if __name__ == '__main__':
main()

another local example

server:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# import socket programming library
import socket

# import thread module
from _thread import *
import threading

print_lock = threading.Lock()

# thread function
def threaded(c):
while True:

# data received from client
data = c.recv(1024)
if not data:
print('Bye')

# lock released on exit
print_lock.release()
break

# reverse the given string from client
data = data[::-1]

# send back reversed string to client
c.send(data)

# connection closed
c.close()


def Main():
host = ""

# reserve a port on your computer
# in our case it is 8888 but it
# can be anything
port = 8888
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.bind((host, port))
print("socket binded to port", port)

# put the socket into listening mode
s.listen(5)
print("socket is listening")

# a forever loop until client wants to exit
while True:

# establish connection with client
c, addr = s.accept()

# lock acquired by client
print_lock.acquire()
print('Connected to :', addr[0], ':', addr[1])

# Start a new thread and return its identifier
start_new_thread(threaded, (c,))
s.close()


if __name__ == '__main__':
Main()

client:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
# Import socket module
import socket


def Main():
# local host IP '127.0.0.1'
host = '127.0.0.1'

# Define the port on which you want to connect
port = 8888

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)

# connect to server on local computer
s.connect((host,port))

# message you send to server
message = "shaurya says geeksforgeeks"
while True:

# message sent to server
s.send(message.encode('ascii'))

# message received from server
data = s.recv(1024)

# print the received message
# here it would be a reverse of sent message
print('Received from the server :',str(data.decode('ascii')))

# ask the client whether he wants to continue
ans = input('\nDo you want to continue(y/n) :')
if ans == 'y':
continue
else:
break
# close the connection
s.close()

if __name__ == '__main__':
Main()

unsolved

  1. why the exception handler is not working?
  2. why can’t open plain text(txt) file?
  3. why more than one threads assigned to a single user?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
import socket
import threading
import os

#Get current directory
currentPath = os.getcwd().replace('\\','/')
# multithreaded server

def handle_conn(sock, address):
print("deal with connection ....")
t = threading.Thread(target=process_conn, args=(sock, address))
t.start()


def process_conn(sock, address):
print(threading.current_thread())

while True: # serve one client multiple times
recv_data = sock.recv(1024)

# until there is no incoming request
if recv_data:


request=recv_data.decode()
print(request)

headers = request.split('\n')
filename = headers[0].split()[1]

headers = "HTTP/1.1 200 OK\n" + "Content-Type: text/html\n\n"
# access HTML file
if filename == '/':
filename = '/index.html'
# access jpg image file
elif filename.endswith(".jpg") :
headers = "HTTP/1.1 200 OK\n" + "Content-Type: image/jpeg\n\n"
# access txt file
elif filename.endswith(".txt") :
headers = "HTTP/1.1 200 OK\n" + "Content-Type: text/plain\n\n"


# headers = "HTTP/1.1 200 OK\n" + "Content-Type: text/html\n\n"
# fin = open(currentPath+filename, "rb")
# content = fin.read()
# fin.close()
# sock.send(headers.encode())
# sock.send(content)
# elif filename.endswith(".jpg") :
# is_img=True
# headers = "HTTP/1.1 200 OK\n" + "Content-Type: image/jpeg\n\n"
# fin = open(currentPath+filename, "rb")
# content = fin.read()
# fin.close()
# sock.send(headers.encode())
# sock.send(content)
try:

# is_img or not:
fin = open(currentPath+filename, "rb")
content = fin.read()
fin.close()
response=headers.encode()+content
# sock.send(headers.encode())
# sock.send(content)

# else :
# fin = open(currentPath+filename, "r")
# content = fin.read()
# fin.close()
# sock.send(headers.encode())
# sock.send(content.encode())

# content = fin.read()
# fin.close()

#response = 'HTTP/1.0 200 OK\n\n' + content

# Error Handling
except FileNotFoundError:
response = 'HTTP/1.0 404 NOT FOUND\n\nFile Not Found'.encode()
except PermissionError:
response = 'HTTP/1.0 403 FORBIDDEN\n\nNo Access Permission'.encode()

# Return an HTTP response

sock.send(response)
# sock.sendall((headers + content).encode())
else:
break
# 5. close socket
print("close socket..")
sock.close()


def main():
# 1. create socket
tcp_server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 2. bind local information
tcp_server_socket.bind(("127.0.0.1", 8888))
# 3.
tcp_server_socket.listen(5)

# 4. wait and accept connection from client
while True:
print(threading.current_thread())
print("waitting ........")
new_client_socket, client_addr = tcp_server_socket.accept()
handle_conn(new_client_socket, client_addr)


if __name__ == '__main__':
main()