1. 程式人生 > >python中網路tcp

python中網路tcp

python中網路tcp

1. tcp簡介""

  • TCP協議,傳輸控制協議(英語:Transmission Control Protocol,縮寫為 TCP)是一種面
    向連線的、可靠的、基於位元組流的傳輸層通訊協議,由IETF的RFC 793定義。 TCP通訊需要經過建立連線、資料傳送、終止連線三個步驟。
    TCP通訊模型中,在通訊開始之前,一定要先建立相關的連結,才能傳送資料,類似於生活中,"打電話
tcp特點:
	1)面向連線
		通訊雙方必須先建立連線才能進行資料的傳輸,雙方都必須為該連線分配必要的系統核心資源,以管理連線的狀態和連線上的傳輸。
		雙方間的資料傳輸都可以通過這一個連線進行。
		完成資料交換後,雙方必須斷開此連線,以釋放系統資源。
		這種連線是一對一的,因此TCP不適用於廣播的應用程式,基於廣播的應用程式請使用UDP協議。
	2)可靠傳輸
		1)TCP採用傳送應答機制
		  TCP傳送的每個報文段都必須得到接收方的應答才認為這個TCP報文段傳輸成功
		2)超時重傳
		   傳送端發出一個報文段之後就啟動定時器,如果在定時時間內沒有收到應答就重新發送這個報文段。
		   TCP為了保證不發生丟包,就給每個包一個序號,同時序號也保證了傳送到接收端實體的包的按序接收。然後接收端實體對已成功收到的包發回一個相應的確認(ACK);如果傳送端實體在合理的往返時延(RTT)內未收到確認,那麼對應的資料包就被假設為已丟失將會被進行重傳。
		3錯誤校驗
		    TCP用一個校驗和函式來檢驗資料是否有錯誤;在傳送和接收時都要計算校驗和。
		4)流量控制和阻塞管理
		   流量控制用來避免主機發送得過快而使接收方來不及完全收下。
	
	TCP與UDP的不同點:
		1)面向連線(確認有建立三方交握,連線已建立才作傳輸。)
		2)有序資料傳輸
		3)重發丟失的資料包
		4)捨棄重複的資料包
		5)無差錯的資料傳輸
		6)阻塞/流量控制

2、tcp客戶端

tcp的客戶端要比伺服器端簡單很多,如果說伺服器端是需要自己買手機、查手機卡、設定鈴聲、等待別人打電話流程的話,那麼客戶端就只需要找一個電話亭,拿起電話撥打即可,流程要少很多
	示例程式碼:
	from socket import *

	# 建立socket
	tcp_client_socket = socket(AF_INET, SOCK_STREAM)

	# 目的資訊
	server_ip = input("請輸入伺服器ip:")
	server_port = int(input("請輸入伺服器port:"))

	# 連結伺服器
	tcp_client_socket.connect((server_ip, server_port))

	# 提示使用者輸入資料
	send_data = input("請輸入要傳送的資料:")

	tcp_client_socket.send(send_data.encode("gbk"))

	# 接收對方傳送過來的資料,最大接收1024個位元組
	recvData = tcp_client_socket.recv(1024)
	print('接收到的資料為:', recvData.decode('gbk'))

	# 關閉套接字
	tcp_client_socket.close()

	

3、tcp伺服器端

如同上面的電話機過程一樣,在程式中,如果想要完成一個tcp伺服器的功能,需要的流程如下:
		1)socket建立一個套接字
		2)bind繫結ip和port
		3)listen使套接字變為可以被動連結
		4)accept等待客戶端的連結
		5)recv/send接收發送資料
    一個很簡單的tcp伺服器如下:
	from socket import *
	# 建立socket
	tcp_server_socket = socket(AF_INET, SOCK_STREAM)
	# 本地資訊
	address = ('', 7788)
	# 繫結
	tcp_server_socket.bind(address)
	# 使用socket建立的套接字預設的屬性是主動的,使用listen將其變為被動的,這樣就可以接收別人的連結了
	tcp_server_socket.listen(128)
	# 如果有新的客戶端來連結伺服器,那麼就產生一個新的套接字專門為這個客戶端服務
	# client_socket用來為這個客戶端服務
	# tcp_server_socket就可以省下來專門等待其他新客戶端的連結
	client_socket, clientAddr = tcp_server_socket.accept()
	# 接收對方傳送過來的資料
	recv_data = client_socket.recv(1024)  # 接收1024個位元組
	print('接收到的資料為:', recv_data.decode('gbk'))
	# 傳送一些資料到客戶端
	client_socket.send("thank you !".encode('gbk'))
	# 關閉為這個客戶端服務的套接字,只要關閉了,就意味著為不能再為這個客戶端服務了,如果還需要服務,只能再次重新連線
	client_socket.close()
	
	//注意 :
		1)recv函式與recvfrom()的區別是 recvfrom()帶有返回的IP地址等資訊
		2)recv()函式只是返回的客戶端發來的資料
		3)可以通過recv()函式返回資料是否為空,判斷客戶端是否斷開連線

4、tcp伺服器端迴圈傳送訊息

import socket
	def main():
		# 建立socket物件
		tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
		# 繫結資訊
		localtion_address = ("",7788)
		tcp_socket.bind(localtion_address)
		# 監聽 使用socket建立的套接字是主動的  使用listen讓其變為被動
		tcp_socket.listen(128)
		# 等待客戶端連線
		while True:
			print("等待新的客戶端連線")
			new_socket, address = tcp_socket.accept()
			print("連線的客戶端資訊為:"+str(address))
			while True:
				recv_data = new_socket.recv(1024)
				if recv_data:
					print("客戶端發來的資訊為:"+recv_data.decode("gbk"))
					new_socket.send("您好,這裡是服務端,收到你的資訊".encode("gbk"))
				else:
					break
			new_socket.close()
		tcp_socket.close()
	if __name__ == "__main__":
		main()