# Send one HTTP header line into socket connectionSocket.send('HTTP/1.1 200 OK\r\n\r\n'.encode(FORMAT))
# Send the content of the requested file to the client for i inrange(0, len(outputdata)): connectionSocket.send(outputdata[i].encode()) connectionSocket.send("\r\n".encode())
connectionSocket.close()
except IOError: # Send response message for file not found connectionSocket.send('HTTP/1.1 404 Not found\r\n\r\n'.encode(FORMAT)) connectionSocket.send('文件不存在\r\n'.encode(FORMAT)) # Close client socket connectionSocket.close()
serverSocket.close() sys.exit() # Terminate the program after sending the corresponding data
多线程 webserver_thread.py
import sys # In order to terminate the program import threading
from socket import *
SERVER = gethostbyname(gethostname()) PORT = 18888 ADDR = (SERVER, PORT)
# Send one HTTP header line into socket connectionSocket.send('HTTP/1.1 200 OK\r\n\r\n'.encode(FORMAT))
# Send the content of the requested file to the client for i inrange(0, len(outputdata)): connectionSocket.send(outputdata[i].encode()) connectionSocket.send("\r\n".encode())
# connectionSocket.close()
except (OSError, IOError): # Send response message for file not found
connectionSocket.send('HTTP/1.1 404 Not found\r\n\r\n'.encode(FORMAT)) # connectionSocket.send('文件不存在\r\n'.encode(FORMAT))
# Close client socket connectionSocket.close()
start() serverSocket.close() sys.exit()
UDP ping 程序
客户端
下面的代码结合了作业的扩展练习 1:
Currently, the program calculates the round-trip time for each packet and prints it out individually. Modify this to correspond to the way the standard ping program works. You will need to report the minimum, maximum, and average RTTs at the end of all pings from the client. In addition, calculate the packet loss rate (in percentage).
UDPPingerClient.py
import socket import time
PORT = 12000 FORMAT = 'utf-8' DISCONNECT_MESSAGE = '!DISCONNECT' SERVER = '127.0.0.1' ADDR = (SERVER, PORT)
for i inrange(1,11): send(f"Ping {i}{time.asctime()}") else: client.close() print(f"""---ping statics--- 10 transmitted, {10 - loss_number} received, {loss_number/10:.2%} loss min/max/avg: {min(time_queue):f}/{max(time_queue):f}/{sum(time_queue)/10:f} s """) # send(input())
UDPPingerServer.py
# We will need the following module to generate randomized lost packets import random from socket import *
# Create a UDP socket # Notice the use of SOCK_DGRAM for UDP packets serverSocket = socket(AF_INET, SOCK_DGRAM)
# Assign IP address and port number to socket serverSocket.bind(('', 12000))
whileTrue: # Generate random number in the range of 0 to 10 rand = random.randint(0, 10) # Receive the client packet along with the address it is coming from message, address = serverSocket.recvfrom(1024) # Capitalize the message from the client message = message.upper()
# If rand is less is than 4, we consider the packet lost and do not respond if rand < 4: continue
# Otherwise, the server responds serverSocket.sendto(message, address
心跳包(Heartbeat packets)
UDPHeartbeatClient.py
import socket import threading import time
PORT = 12000 FORMAT = 'utf-8' DISCONNECT_MESSAGE = '!DISCONNECT' SERVER = '127.0.0.1' ADDR = (SERVER, PORT)
defsend_length(): global noTransferSequence while noTransferSequence: client.sendto(str(sequenceLength).encode(FORMAT), ADDR) status = client.recv(2048).decode() if status == 'Length OK': noTransferSequence = False # 创建线程监听收到的信息 threading.Thread(target=listen_recv).start()
defhandle_heatbeat(sequence_length): while sequence_length: time.sleep(0.1) now_time = time.time() latest_send = sendTimeSequence[-1] # 获取最近一次客户端发送心跳包的时间 if now_time - latest_send > TIMEOUT: serverSocket.close() break
defstart(): global noSequenceLength, noThreadMonitoring print('Ready to serve') latest_number = 0 sequence_length = 0 whileTrue: try: # Generate random number in the range of 0 to 10 rand = random.randint(0, 10) # Receive the client packet along with the address it is coming from message, address = serverSocket.recvfrom(1024) # If rand is less is than 1, we consider the packet lost and do not respond if rand < 1: if noSequenceLength: serverSocket.sendto(b'Retransmission', address) continue
# Otherwise, the server responds msg = message.decode() if noSequenceLength: # 此时已经收到序列长度,对第一次收到的序列长度进行处理 sequence_length = int(msg[:5]) noSequenceLength = False serverSocket.sendto(b'Length OK', address) continue
number = int(msg[:sequence_length]) sendTimeSequence.append(float(msg[sequence_length:])) if noThreadMonitoring: threading.Thread(target=handle_heatbeat,args=(sequence_length,)).start() noThreadMonitoring = False
for i inrange(latest_number + 1, number): # 若间隔为1,则代表未丢失,不需回复 serverSocket.sendto(f'{i} have lost'.encode(), address) latest_number = number except OSError: print('CLOSE') break
msg = "\r\n I love computer networks!"# 信息前面需空行 endmsg = "\r\n.\r\n" recv = []
# Choose a mail server (e.g. Google mail server) and call it mailserver mailserver = "smtp.163.com"
# Create socket called sslClientSocket and establish a TCP connection with mailserver clientSocket = socket(AF_INET, SOCK_STREAM) clientSocket.connect((mailserver, 25))
recv.append(clientSocket.recv(1024).decode())
if recv[-1][:3] != '220': print('220 reply not received from server.') print(recv[-1])
# Send HELO command and print server response. heloCommand = 'HELO Alice\r\n' clientSocket.send(heloCommand.encode()) recv.append(clientSocket.recv(1024).decode()) print(recv[-1])
# Send RCPT TO command and print server response. ToCommand = 'rcpt to: <recipient_email_address>\r\n' clientSocket.send(ToCommand.encode()) recv.append(clientSocket.recv(1024).decode()) print(recv[-1])
# Send DATA command and print server response. DataCommand = 'data' clientSocket.send(DataCommand.encode())
# Send message data. header = f''' from: <your_email_address> to: <recipient_email_address> subject: test ''' clientSocket.send((header + msg).encode())
# Message ends with a single period. clientSocket.send(endmsg.encode()) recv.append(clientSocket.recv(1024).decode()) print(recv[-1])
# Send QUIT command and get server response. QuitCommand = 'QUIT\r\n' clientSocket.send(QuitCommand.encode()) recv.append(clientSocket.recv(1024).decode()) print(recv[-1]) recv.append(clientSocket.recv(1024).decode()) print(recv[-1])
原文:Mail servers like Google mail (address: smtp.gmail.com, port: 587) requires your client to add a Transport Layer Security (TLS) or Secure Sockets Layer (SSL) for authentication and security reasons, before you send MAIL FROM command. Add TLS/SSL commands to your existing ones and implement your client using Google mail server at above address and port.
因为换个端口号就能使用 SSL 协议,接下来继续用网易做示范。
smtp.163.com SSL协议的端口号为465/994,任选其一使用
# SSL 加密 import base64 import ssl
from socket import *
msg = "\r\n I love computer networks!" endmsg = "\r\n.\r\n" recv = []
# Choose a mail server (e.g. Google mail server) and call it mailserver mailserver = "smtp.163.com"
# Create socket called sslClientSocket and establish a TCP connection with mailserver clientSocket = socket(AF_INET, SOCK_STREAM) clientSocket.connect((mailserver, 465))
# Send RCPT TO command and print server response. ToCommand = 'rcpt to: <recipient_email_address>\r\n' sslClientSocket.send(ToCommand.encode()) recv.append(sslClientSocket.recv(1024).decode()) print(recv[-1])
# Send DATA command and print server response. DataCommand = 'data' sslClientSocket.send(DataCommand.encode())
# Send message data. header = f''' from: <your_email_address> to: <recipient_email_address> subject: test ''' sslClientSocket.send((header + msg).encode())
# Message ends with a single period. sslClientSocket.send(endmsg.encode()) recv.append(sslClientSocket.recv(1024).decode()) print(recv[-1])
# Test URL:http://gaia.cs.umass.edu/wireshark-labs/HTTP-wireshark-file1.html import sys
from socket import *
iflen(sys.argv) <= 1: print('Usage : "python ProxyServer.py server_ip"\n' '[server_ip : It is the IP Address Of Proxy Server\n' 'The default address is 0.0.0.0') IP = '' # sys.exit(2) else: IP = sys.argv[1]
PORT = 8086 FORMAT = 'utf-8'
# Create a server socket, bind it to a port and start listening tcpSerSock = socket(AF_INET, SOCK_STREAM) tcpSerSock.bind((IP, PORT)) tcpSerSock.listen()
while1: # Start receiving data from the client print('Ready to serve...') tcpCliSock, addr = tcpSerSock.accept() print('Received a connection from:', addr) message = tcpCliSock.recv(2048).decode(FORMAT) print(message) # Extract the filename from the given message print(message.split()[1]) print(message.split()[1]) filename = message.split()[1].partition("//")[2] # filename = message.split()[1].split(':')[0] print(filename) fileExist = "false" filetouse = filename.replace('/', '_') print(filetouse) try: # Check wether the file exist in the cache f = open(filetouse, "r") outputdata = f.readlines() fileExist = "true" # ProxyServer finds a cache hit and generates a response message tcpCliSock.send("HTTP/1.0 200 OK\r\n".encode(FORMAT)) tcpCliSock.send("Content-Type:text/html\r\n".encode(FORMAT))
# Send the content of the requested file to the client for data in outputdata: tcpCliSock.send(data.encode(FORMAT)) tcpCliSock.send("\r\n".encode(FORMAT))
print('Read from cache')
# Error handling for file not found in cache except IOError: if fileExist == "false": # Create a socket on the proxyserver c = socket(AF_INET, SOCK_STREAM) # Fill in start. # Fill in end. hostn = filename.replace("www.", "", 1).split('/')[0] print(f'Host: {hostn}') try: # Connect to the socket to port 80 c.connect((hostn, 80))
# Create a temporary file on this socket and ask port 80 for the file requested by the client fileobj = c.makefile('rwb', 0) fileobj.write(message.encode(FORMAT))
# Read the response into b_buffer b_buffer = fileobj.read() # 这里没有 decode() print(b_buffer) # Create a new file in the cache for the requested file. # Also send the response in the b_buffer to client socket and the corresponding file in the cache tcpCliSock.send(b_buffer)
except: print('Illegal request') else: # HTTP response message for file not found tcpCliSock.send('HTTP/1.1 404 Not Found\r\n'.encode(FORMAT)) tcpCliSock.send('Content-Type:text/html\r\n'.encode(FORMAT)) withopen('404 Not Found.html', "r") as f: notfound_data = f.readlines() for data in notfound_data: tcpCliSock.send(data.encode(FORMAT)) tcpCliSock.send("\r\n".encode(FORMAT))
# Close the client and the server sockets tcpCliSock.close() tcpSerSock.close()