TCP/IP Socketpython
若是使用TCP協議來傳遞數據,客戶端和服務器端須要分別通過如下步驟:算法
server: 建立socket對象 - bind(綁定socket到指定地址和端口) - listen(在綁定的端口監聽來自客戶端的鏈接) - accept(接受客戶端的鏈接請求) - recv(接收發來的數據)- close(關閉這次鏈接)
client: 建立socket對象 - connect(由內核分配一個端口發出服務器鏈接請求)- send(發送數據)- close(關閉這次鏈接)服務器
詳細步驟爲:socket
python 編寫server的步驟:tcp
第一步是建立socket對象。調用socket構造函數。如:
sock = socket.socket( family, type )
family參數表明地址家族,可爲AF_INET或AF_UNIX。AF_INET家族包括Internet地址,AF_UNIX家族用於同一臺機器上的進程間通訊。
type參數表明套接字類型,可爲SOCK_STREAM(流套接字,實現TCP)和SOCK_DGRAM(數據報套接字,用於實現UDP)。函數
第二步是將socket綁定到指定地址。這是經過socket對象的bind方法來實現的:
sock.bind( address )
由AF_INET所建立的套接字,address地址必須是一個雙元素元組,格式是(host,port)。host表明主機,port表明端口號。若是端口號正在使用、主機名不正確或端口已被保留,bind方法將引起socket.error異常。大數據
第三步是使用socket套接字的listen方法接收鏈接請求。優化
sock.listen( backlog )spa
backlog指定最多容許多少個客戶鏈接到服務器。它的值至少爲0。收到鏈接請求後,這些鏈接請求須要排隊,tcp的server儘管能夠同時接受n個客服端鏈接,但只能和第一個鏈接的客服端互相通訊,當第一個tcp鏈接的客戶端關閉後才能和第二個鏈接申請的客戶端通訊,即後邊的被阻塞了,一次只能和一個tcp客戶端進行通訊。code
第四步是服務器套接字經過socket的accept方法等待客戶請求一個鏈接。
connection, address = socke.accept()
調用accept方法時,socket會時入「waiting」狀態。客戶請求鏈接時,服務器將會建立一個新的socket實例,表明新創建的鏈接的服務端,而後返回這個新的socket。accept方法返回一個含有兩個元素的元組(connection,address)。第一個元素connection是新的socket對象,服務器必須經過它與客戶通訊;第二個元素 address是客戶的Internet地址。
第五步是處理階段,服務器和客戶端經過send和recv方法通訊(傳輸數據)。例如服務器調用send,並採用字符串形式向客戶發送信息。send方法返回已發送的字符個數。服務器使用recv方法從客戶接收信息。調用recv 時,服務器必須指定一個整數,它對應於可經過本次方法調用來接收的最大數據量。recv方法在接收數據時會進入「blocked」狀態,最後返回一個字符串,用它表示收到的數據。若是發送的數據量超過了recv所容許的,數據會被截短。多餘的數據將緩衝於接收端。之後調用recv時,多餘的數據會從緩衝區刪除(以及自上次調用recv以來,客戶可能發送的其它任何數據)。
傳輸結束,服務器調用socket的close方法關閉鏈接。
if __name__ == '__main__': import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost', 8001)) sock.listen(5) while True: connection,address = sock.accept() try: connection.settimeout(5) buf = connection.recv(1024) if buf == '1': connection.send('welcome to server!') else: connection.send('please go out!') except socket.timeout: print 'time out' connection.close()
編寫client步驟
建立一個socket以鏈接服務器:sock = socket.socket( family, type )
使用socket的connect方法鏈接服務器。對於AF_INET家族,鏈接格式以下:
socket.connect( (host,port) )
host表明服務器主機名或IP,port表明服務器進程所綁定的端口號。如鏈接成功,客戶就可經過套接字與服務器通訊,若是鏈接失敗,會引起socket.error異常。
處理階段,客戶和服務器將經過send方法和recv方法通訊。
傳輸結束,客戶經過調用socket的close方法關閉鏈接。
if __name__ == '__main__': import socket sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.connect(('localhost', 8001)) import time time.sleep(2) sock.send('1') print sock.recv(1024) sock.close()
並行仿真優化
Socket方式已經能夠知足本系統的需求,即每完成一次screening round,主節點就把系統狀態更新信息發送給主實體服務器,這樣用戶就能夠經過和實體服務器交互獲取系統狀態了。本人的在傳統並行仿真優化算法的基礎上作出了擴展,利用貪心策略將排序時間從O(N2)下降到了O(NlogN),並證實了算法的正確性。不過論文暫時尚未寫完。
也能夠試一試SocketServer模塊實現非阻塞通訊。
RPC通訊
這是用的比較多的東西,好比用Thrift。
比較忙,之後再寫。