計算機,顧名思義便是用來作計算。於是也須要輸入和輸出,輸入須要計算的條件,輸出計算結果。這些輸入輸出能夠抽象爲I/O(input output)。python
Unix的計算機處理IO是經過文件的抽象。計算機不一樣的進程之間也有輸入輸出,也就是通訊。所以這這個通訊也是經過文件的抽象文件描述符來進行。服務器
在同一臺計算機,進程之間能夠這樣通訊,若是是不一樣的計算機呢?網絡上不一樣的計算機,也能夠通訊,那麼就得使用網絡套接字(socket)。socket就是在不一樣計算機之間進行通訊的一個抽象。他工做於TCP/IP協議中應用層和傳輸層之間的一個抽象。以下圖:網絡
socket保證了不一樣計算機之間的通訊,也就是網絡通訊。對於網站,通訊模型是客戶端服務器之間的通訊。兩個端都創建一個socket對象,而後經過socket對象對數據進行傳輸。一般服務器處於一個無線循環,等待客戶端鏈接:併發
socket接口是操做系統提供的,調用操做系統的接口。固然高級語言通常也封裝了好用的函數接口,下面用python代碼寫一個簡單的socket服務端例子:socket
server.pytcp
import socket HOST = 'localhost' # 服務器主機地址 PORT = 5000 # 服務器監聽端口 BUFFER_SIZE = 2048 # 讀取數據大小 # 建立一個套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 綁定主機和端口 sock.bind((HOST, PORT)) # 開啓socket監聽 sock.listen(5) print 'Server start, listening {}'.format(PORT) while True: # 創建鏈接,鏈接爲創建的時候阻塞 conn, addr = sock.accept() while True: # 讀取數據,數據還沒到來阻塞 data = conn.recv(BUFFER_SIZE) if len(data): print 'Server Recv Data: {}'.format(data) conn.send(data) print 'Server Send Data: {}'.format(data) else: print 'Server Recv Over' break conn.close() sock.close()
client.py函數
import socket HOST = 'localhost' PORT = 5000 BUFFER_SIZE = 1024 # 建立客戶端套接字 sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 鏈接到服務器 sock.connect((HOST, PORT)) try: message = "Hello" # 發起數據給服務器 sock.sendall(message) amount_received = 0 amount_expected = len(message) while amount_received < amount_expected: # 接收服務器返回的數據 data = sock.recv(10) amount_received += len(data) print 'Client Received: {}'.format(data) except socket.errno, e: print 'Socket error: {}'.format(e) except Exception, e: print 'Other exception: %s'.format(e) finally: print 'Closing connection to the server' sock.close()
python代碼寫套接字很簡單。傳說的TCP三次握手又是如何體現的呢?什麼是三次握手呢?網站
用下面的比喻就是spa
C:約麼?操作系統
S:約
C:好的
約會
這樣就創建了一個TCP鏈接會話。若是是要斷開鏈接,大體過程是:
上圖也很清晰的代表了三次握手的socket具體過程。
至此,客戶端和服務器的socket通訊鏈接創建完成,剩下的就是兩個端的鏈接對象收發數據,從而完成網絡通訊。