《計算機網路:自頂向下方法》第二章配套實驗

《計算機網路:自頂向下方法》第二章配套實驗

來自專欄 myk的CS學習之旅

寫個大概的。。注釋?方便以後複習python socket編程。

具體的實驗中文翻譯在這裡:

myk502/Computer-Networking-A-Top-Down-Approach-NOTES?

github.com圖標

實驗一:Tiny Web Server in Python

大概就是用python編寫一個簡單的Web伺服器,能夠把本地的html文件通過TCP connection傳輸到遠處主機。

代碼:

from socket import *serverSocket = socket(AF_INET, SOCK_STREAM)try: serverSocket.bind((, 6789))#attach port number 6789 to welcome socket serverSocket.listen(1) if True: print "The sever is ready to receive" connectionSocket, addr = serverSocket.accept() try: message = connectionSocket.recv(4096) filename = message.split()[1] f = open(filename[1:]) outputdata = f.read() #Read text form the html file #Create the header line header = HTTP/1.1 200 OK
Connection: close
Content-Type: text/html; charset=utf-8
Content-Length: %d

%(len(outputdata)) connectionSocket.send(header.encode(utf-8)) for i in range(0, len(outputdata)): connectionSocket.send(outputdata[i]) connectionSocket.close() except IOError: header = HTTP/1.1 404 Found connectionSocket.send(header.encode()) finally: connectionSocket.close()finally: serverSocket.close()

寫個注釋,免得以後忘記了。

第一句話,import socket編程所需要的所有庫。

第二句話,創建一個socket。第一個參數意思為創建IPV4連接,第二個參數意思為創建connection類型的連接(即TCP)。注意,這裡的TCP socket 類型為welcome socket。

socket的bind方法,給socket分配一個埠號。

Welcome Socket的 listen方法,使得這個socket進入監聽模式,參數1代表在等待隊列上的最大數量。

Welcome的accept方法,有點類似C的sigsuspend?(抱歉我想不出第二個類似的東西)。。。就是暫時暫停程序的執行,等到一個新的TCP連接被建立,然後返回的兩個參數,分別為Connection Socket ,以及TCP連接發起方的地址。

Socket的recv方法,從socket讀入數據,參數為緩衝區大小。

下面的幾句話是框架給的,簡單的parse,也看不太懂,不分析了。

然後打開一個文件,對file descrpitor 調用read方法,讀進來的是一行一行的內容。

接下來需要先把HTTP Header傳中文給客戶端。下面的幾句話都是header內容,注意一定要加charset=utf-8! 否則瀏覽器不會識別中文。

後面的一些都比較簡單,不說了。

實驗二:UDP Ping伺服器

比較簡單。。一看就懂

補一個python socket編程常用方法:

https://gist.github.com/myk502/41264b91f708d1a95d3007d87c4f82e1?

gist.github.com

客戶端:

from socket import *import timeserverName = localhostserverPort = 12000clientSocket = socket(AF_INET, SOCK_DGRAM)clientSocket.settimeout(1)for i in range(0, 10): sendTime = time.time() message = (Ping %d %s % (i + 1, sendTime)).encode() try: clientSocket.sendto(message, (serverName, serverPort)) modifiedMessage, serverAddress = clientSocket.recvfrom(2048) rtt = time.time() - sendTime print(Sequence %d: Reply from %s RTT = %.3fs % (i + 1, serverName, rtt)) except Exception as e: print(Sequence %d: Request timed out % (i + 1)) print eclientSocket.close()

伺服器:

import randomfrom socket import *serverSocket = socket(AF_INET, SOCK_DGRAM)serverSocket.bind((, 12000))while True: rand = random.randint(0, 10) message, address = serverSocket.recvfrom(1024) message = message.upper() if (rand < 4): continue serverSocket.sendto(message, address)

SMTP 客戶端

這個實驗要求實現一個簡單的smtp客戶端,連接到伺服器,並發送郵件。

所以首先得按照書上說的, 用telnet連接到郵件伺服器,登錄,發一封郵件,再寫程序。

但是網易郵件伺服器似乎有限制,一天只能發一封郵件,具體表現為:先用telnet發了一封郵件,可以發送,發第二封就不行了。

所以這個代碼也不能運行,顯示是垃圾郵件,但是理論上是可以跑的。。

def receiveFromServer(): msg = clientSocket.recv(1024) print msg return msgfrom socket import *msg = "What to eat tonight?
"endmsg = "
.
"mailServer = smtp.163.comclientSocket = socket(AF_INET, SOCK_STREAM) # The socket for TCP ConnectionclientSocket.connect((mailServer, 25))recv = receiveFromServer()if(recv[:3] != 220): print 220 reply not received from server.heloCommand = HELO fanese
clientSocket.sendall(heloCommand)recv1 = receiveFromServer()if(recv1[:3] != 250): print 250 reply not received from server.#Next,we need to login the serverclientSocket.sendall(auth login
)receiveFromServer()clientSocket.sendall(ZmFuZXNlbXlrQDE2My5jb20=
)receiveFromServer()clientSocket.sendall(balabalabalba
)#The base64 code of your passwordreceiveFromServer()# Send mail from commandclientSocket.sendall(mail from: <fanesemyk@163.com>
)receiveFromServer()clientSocket.sendall(rcpt to: <525039107@qq.com>
)receiveFromServer()clientSocket.sendall(data
)clientSocket.recv(1024)clientSocket.sendall(from:fanesemyk@163.com
)clientSocket.sendall(to:525039107@qq.com
)clientSocket.sendall(subject:kuku is smart
)clientSocket.sendall(Content-Type:text/plain
)#WTF?clientSocket.sendall(
)clientSocket.sendall(msg)clientSocket.sendall(endmsg)receiveFromServer()clientSocket.sendall(quit
)receiveFromServer()

實驗四的給的框架代碼有嚴重的問題,我怎麼跑都跑不起來。。最近比較忙,先擱置一下,等樓主完成了CSAPP的Tiny Web Server 後,再來把這個版本完成。


推薦閱讀:

想問下php的socket的工作流程是什麼?
leader/follower, 半同步半非同步 和 事件驅動的關係是什麼?
Socket 和 TCP 有什麼聯繫?建立Socket,操作系統主要是做了哪些事?

TAG:計算機網路 | Socket | Python |