diff --git a/code/reference/ch_socket/SMTPClient.py b/code/reference/ch_socket/SMTPClient.py index bfec76a..accfa03 100644 --- a/code/reference/ch_socket/SMTPClient.py +++ b/code/reference/ch_socket/SMTPClient.py @@ -1,66 +1,71 @@ from socket import * from base64 import * - mailfrom = "mail from:2@test.com\r\n" rcptto = "rcpt to:1@test.com\r\n" data = "data\r\n" quitmsg = "quit\r\n" -msg = "\r\n I love computer networks!" +# 填写代码使程序发送的邮件中包含内容为 "Hello World!"。 +msg = "Hello World!" + endmsg = "\r\n.\r\n" -#此处使用易邮邮件服务器软件搭建了一个内网邮件服务器 -mailserver = '10.130.82.62' + +#本地搭建的邮件服务器IP地址。 +mailserver = 'localhost' +# 在端口25上启动邮件服务器。 mailport = 25 connectaddress = (mailserver, mailport) -# Create socket called clientSocket and establish a TCP connection with mailserver +# 创建 socket 和邮件服务器建立 TCP 连接。 clientSocket = socket(AF_INET, SOCK_STREAM) clientSocket.connect(connectaddress) - recv = clientSocket.recv(1024) -print (recv) -if recv[:3] != '220': + +if recv.decode()[:3] != '220': print ('220 reply not received from server.') -# Send HELO command and print server response. + +# 发送 HELO 命令,打印服务器响应。 heloCommand = 'HELO Alice\r\n' clientSocket.send(bytes(heloCommand.encode())) recv1 = clientSocket.recv(1024) -print (recv1.decode()) -if recv1[:3] != '250': + +if recv1.decode()[:3] != '250': print ('250 reply not received from server.') - -#print('000000000000000') -#从命令和打印服务器响应发送邮件。 + +#发送登陆认证信息 login = b'auth login\r\n' clientSocket.send(login) recv2 = clientSocket.recv(1024).decode('utf-8') -print ('222+',recv2) - +print ('登陆认证',recv2) +#发送用户名 userCommand = b64encode('2@test.com'.encode('utf-8')) clientSocket.send((str(userCommand,encoding='utf-8')+'\r\n').encode()) recv3 = clientSocket.recv(1024).decode('utf-8') -print ('333+',recv3) - +print ('用户名',recv3) +#发送密码 password = b64encode('2'.encode('utf-8')) clientSocket.send((str(password,encoding='utf-8')+'\r\n').encode()) recv4 = clientSocket.recv(1024).decode('utf-8') -print ('444+',recv4) - -#print('0000000000000000') +print ('密码',recv4) +# 发送 MAIL FROM 命令,打印服务器响应。 clientSocket.send(bytes(mailfrom.encode())) check = clientSocket.recv(1024) print(check) +# 发送 RCPT TO 命令,打印服务器响应。 clientSocket.send(bytes(rcptto.encode()))#将RCPT发送到命令和打印服务器响应。 check1 = clientSocket.recv(1024) print(check1) +# 发送 DATA 命令,打印服务器响应。 clientSocket.send(bytes(data.encode()))#发送数据命令和打印服务器响应。 check2 = clientSocket.recv(1024) print(check2) +# 发送邮件内容。消息以单个"." 结束。 clientSocket.send(bytes((mailfrom+msg+endmsg).encode()))#发送消息数据。 check3 = clientSocket.recv(1024) print(check3) -#发送退出命令并获得服务器响应。 +# 发送 QUIT 命令,获取服务器响应。 clientSocket.send(bytes(quitmsg.encode())) check4 = clientSocket.recv(1024) print(check4) -clientSocket.close() + +clientSocket.close() \ No newline at end of file diff --git a/code/reference/ch_socket/Webserver.py b/code/reference/ch_socket/Webserver.py new file mode 100644 index 0000000..fee4e57 --- /dev/null +++ b/code/reference/ch_socket/Webserver.py @@ -0,0 +1,50 @@ +from socket import * +import sys + +# 准备服务器端 socket +serverSocket = socket(AF_INET, SOCK_STREAM) +# 设定端口号 +serverPort = 80 +# 绑定地址(host,port)到套接字 +serverSocket.bind(("localhost", serverPort)) +# 开始 TCP 监听,该值至少为 1 +serverSocket.listen(1) +while True: + # 建立连接 + print('Ready to serve...') + + # 收到客户端请求时建立一个新连接 + connectionSocket, addr = serverSocket.accept() + + try: + + # 按需补充,接受来自客户端的请求 + message = connectionSocket.recv(1024).decode() + + # 从消息中提取所请求对象的路径 + # 路径是HTTP标头的第二部分,由[1]标识 + filename = message.split()[1] + # 因为HTTP请求的提取路径包括一个字符“ \”,我们从第二个字符读取路径 + f = open(filename[1:]) + + # 将请求文件的全部内容存储在临时缓冲区中 + outputdata = f.read() + # 将HTTP响应标头行发送到连接套接字 + connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n".encode()) + # 将请求文件的内容发送到客户端 + for i in range(0, len(outputdata)): + connectionSocket.send(outputdata[i].encode()) + connectionSocket.send("\r\n".encode()) + connectionSocket.close() + except IOError: + + # 按需补充代码:发送未找到文件的响应消息 + connectionSocket.send("HTTP/1.1 404 Not Found\r\n\r\n".encode()) + connectionSocket.send("

404 Not Found

\r\n".encode()) + # 按需补充代码:关闭客户端 socket + connectionSocket.close() +serverSocket.close() +sys.exit() + + + diff --git a/code/reference/ch_socket/Websever.py b/code/reference/ch_socket/Websever.py deleted file mode 100644 index d901408..0000000 --- a/code/reference/ch_socket/Websever.py +++ /dev/null @@ -1,62 +0,0 @@ -# Import socket module -from socket import * -import sys # In order to terminate the program - -# Create a TCP server socket -#(AF_INET is used for IPv4 protocols) -#(SOCK_STREAM is used for TCP) - -serverSocket = socket(AF_INET, SOCK_STREAM) - -# Assign a port number -serverPort = 80 - -# 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('The server is ready to receive') - - # Set up a new connection from the client - connectionSocket, addr = serverSocket.accept() - - # If an exception occurs during the execution of try clause - # the rest of the clause is skipped - # If the exception type matches the word after except - # the except clause is executed - try: - # Receives the request message from the client - message = connectionSocket.recv(1024).decode() - # Extract the path of the requested object from the message - # The path is the second part of HTTP header, identified by [1] - filename = message.split()[1] - # Because the extracted path of the HTTP request includes - # a character '\', we read the path from the second character - f = open(filename[1:]) - # Store the entire contenet of the requested file in a temporary buffer - outputdata = f.read() - # Send the HTTP response header line to the connection socket - connectionSocket.send("HTTP/1.1 200 OK\r\n\r\n".encode()) - - # Send the content of the requested file to the connection socket - for i in range(0, len(outputdata)): - connectionSocket.send(outputdata[i].encode()) - connectionSocket.send("\r\n".encode()) - - # 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".encode()) - connectionSocket.send("

404 Not Found

\r\n".encode()) - # Close the client connection socket - connectionSocket.close() - -serverSocket.close() -sys.exit()#Terminate the program after sending the corresponding data diff --git a/data/copyright.tex b/data/copyright.tex index 8f42736..96c10ce 100644 --- a/data/copyright.tex +++ b/data/copyright.tex @@ -15,10 +15,17 @@ \begin{tabular*}{0.85\textwidth}{rm{0.8\textwidth}} \large $\copyright$ & \sffamily{\color{darkgray} 2021 计算机网络教案社区} \hspace{0.3em}\includegraphics[width=0.6cm]{figure/logo} \\ - & \footnotesize 本教案中所有原创内容,包括但不限于文字、图片、图表、版面设计、标题等的版权归计算机网络教案社区所有,并受著作权法保护。 \\ - & \footnotesize 读者可以将本教案的全部或部分内容{\color{purple}免费用于非商业用途},但在使用本教案内容时请注明来源和版权声明,即“内容来自:计算机网络教案社区,版权归原作者所有”。 \\ - & \footnotesize 对于不遵守此声明或者其他违法使用本教案内容者,我们将保留依法追究其侵权责任的权利。 \\ - & \footnotesize 本教案如涉及特定版权内容,请版权方在社区提供相关信息以便及时删除该内容。 \\ + & \footnotesize 本教案中所有原创内容, + 包括但不限于文字、图片、图表、版面设计、 + 标题等的版权归计算机网络教案社区所有,并受著作权法保护。 \\ + & \footnotesize 读者可以将本教案的全部或部分内容{\color{purple}免费用于非商业用途}, + 但在使用本教案内容时请注明来源和版权声明, + 即“内容来自:计算机网络教案社区,版权归原作者所有”。 \\ + & \footnotesize 对于不遵守此声明或者其他违法使用本教案内容者, + 我们将保留依法追究其侵权责任的权利。 \\ + & \footnotesize 本教案如涉及特定版权内容, + 请版权方在社区提供相关信息以便及时删除该内容。 \\ + & \footnotesize 清华大学出版社参与了版式、字体设计等工作。 \end{tabular*} \renewcommand{\arraystretch}{1} \end{center} diff --git a/data/preface.tex b/data/preface.tex index 6cb717c..d031321 100644 --- a/data/preface.tex +++ b/data/preface.tex @@ -18,12 +18,15 @@ 在附录\ref{app:cheatsheet}中做了汇总,方便老师快速查询。 在实际使用中,任课老师可以根据具体授课需要在本指导书的基础上通过 增删、组合、修改等方法设计适合自身课程的实验方案。 +本指导书基于Latex编写, +源代码可以从 \href{https://gitee.com/xphi1980/nap_instructions}{Gitee} 获取。 由于时间仓促,加之编者水平有限, 本指导书中缺点和疏漏在所难免。 作为社区项目,恳请广大读者和同行专家批评指正, 同时欢迎更多读者和专家参与本项目的编纂和开发。 + \vspace{1em} 本实验指导书各章节主要编纂人员如下: