一、Socket簡介
1、不同電腦上的進程如何通信?
進程間通信的首要問題是如何找到目標進程,也就是操作系統是如何唯一標識一個進程的!
在一臺電腦上是只通過進程號PID,但在網絡中是行不通的,因為每臺電腦的IP可能都是不一樣的,因此TCP/IP協議族通過使用IP地址+端口號的方式來標識任意一臺主機的應用進程。
因此,利用IP地址 + 協議 + 端口號就可以用來標識網絡進程了,網絡中可以利用這個標識來與其他進程通信。
?
2.什么是socket
Socket簡稱為套接字,是進程間通信的一種方式,它與其他進程間通信的一個不同之處在于:它能實現不同主機間的進程間通信,網絡上各種各樣的服務大多是基于Socket來完成的。
?
二、TCP簡介
1.介紹:TCP協議,傳輸控制協議(Transmission Control Protocol)是一種面向連接的、可靠的、基于字節流的傳輸層通信協議。
2.通信流程:建立連接、數據傳輸、終止連接,就類似我們生活中的“打電話”。
三、TCP特點:
1.面向連接:通信前必須先建立連接才能進行數據傳輸,雙方都必須為該連接分配必要的系統內核資源。
2.可靠傳輸:主要體現在:
1). TCP采用發送應答機制:TCP發送的每個報文都必須得到接收方的應答才能成功傳輸該報文。
2). 超時重傳:如果發出的報文在一段時間內沒有收到應答那么就重新發送這個報文段。此外,TCP是為每個包都分配一個序號,用來保證不會發送方丟包和用于在接收端重組。
3). 錯誤檢驗:TCP用一個校驗和函數來校驗數據是否有誤,
? ?4). 流量控制和阻塞管理:用來避免主機發送得過快而使接收方來不及全部收下。
?
四、UDP協議
UDP是一中無需建立連接就能通信的協議,只需要發送數據即可。因此一般適用于廣播的應用程序。
?
五、TCP與UDP的不同點
- 面向連接(確認有創建三方交握,連接已創建才作傳輸。)
- 有序數據傳輸
- 重發丟失的數據包
- 舍棄重復的數據包
- 無差錯的數據傳輸
- 阻塞/流量控制
?
六、TCP/IP協議族
互聯網協議包含了上百種協議標準,但是最重要的兩個協議是TCP和IP協議,因此一般把互聯網的協議簡稱為TCP/IP協議族。
?
七、TCP/IP協議傳輸示意圖
以QQ間發送消息為例!
?
八、TCP通信模型
主要是使用TCP協議來進行通信!
?
注意點:
- tcp服務器一般情況下都需要綁定端口,否則客戶端找不到這個服務器
- tcp客戶端一般不綁定,因為是主動鏈接服務器,所以只要確定好服務器的ip、port等信息就好,本地客戶端可以隨機
- tcp服務器中通過listen可以將socket創建出來的主動套接字變為被動的,這是做tcp服務器時必須要做的
- 當客戶端需要鏈接服務器時,就需要使用connect進行鏈接,udp是不需要鏈接的而是直接發送,但是tcp必須先鏈接,只有鏈接成功才能通信
- 當一個tcp客戶端連接服務器時,服務器端會有1個新的套接字,這個套接字用來標記這個客戶端,單獨為這個客戶端服務
- listen后的套接字是被動套接字,用來接收新的客戶端的鏈接請求的,而accept返回的新套接字是標記這個新客戶端的
- 關閉listen后的套接字意味著被動套接字關閉了,會導致新的客戶端不能夠鏈接服務器,但是之前已經鏈接成功的客戶端正常通信。
- 關閉accept返回的套接字意味著這個客戶端已經服務完畢
- 當客戶端的套接字調用close后,服務器端會recv解堵塞,并且返回的長度為0,因此服務器可以通過返回數據的長度來區別客戶端是否已經下線
?
代碼實現如:
1 import socket
2
3
4 def main():
5 pass
6 # 1.創建TCP套接字
7 tcp_sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
8 # 設置地址可重用
9 tcp_sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
10 # 2.把套接字綁定到主機上
11 tcp_sock.bind(('', 6060))
12 # 3.被動套接字
13 tcp_sock.listen(128)
14 print('{}正在監聽中'.format(tcp_sock.getsockname()))
15 # 4.與客戶端進行連接
16 while True:
17 client, addr = tcp_sock.accept() # Ctrl+Shift +i
18 print('已經連接到了客戶端:{}'.format(addr))
19 # 接收來自客戶端的消息
20 data = client.recv(1024)
21 print(data.decode('utf-8'))
22 # 消息一經發送完畢就斷開了連接
23 client.close() # 短連接
24
25 tcp_sock.close()
26
27
28 if __name__ == '__main__':
29 main()
?