TCP服務端(以字節串傳輸信息)
import socket
1、創建套接字
sockfd =?socket.socket(socket_family = AF_INET,socket_type = SOCK_STREAM,proto = 0)
功能:創建一個IPv4的流式套接字,括號中的創建IPv4流式套接字的時候可以不寫,有缺省值。
參數:socket_family 地址族類型 AF_INET?表示IPv4網絡通信
socket_type 套接字類型 SOCK_STREAM?流式??SOCK_DGRAM? 數據報
proto 通常為0(選擇子協議)
返回值:返回一個套接字對象
2、綁定IP端口
sockfd.bind(("IP地址",端口號))
功能:綁定IP地址和端口號
參數:二元元組
3、將套接字設置為可監聽
sockfd.listen(n)
功能:將套接字設置為監聽套接字,并創建監聽隊列(只有是監聽套接字,才可以連接客戶端)
參數:監聽對象的大小 n為大于0的正整數
一個監聽套接字可以連接多個客戶端
4、等待客戶端的連接
connfd,addr = sockfd.accept()
功能:阻塞等待客戶端連接,返回客戶端的套接字和地址元組
返回值:connfd 一個新的套接字,用于和客戶端通信
addr 連接的客戶端的地址(元組)(ip,port)
阻塞函數:當程序運行到阻塞函數位置,如果某種預期條件沒有達成則暫停繼續運行,直到條件達成在繼續運行
5、消息接收和發送
data = connfd.recv(buffersize)
data為connfd套接字接收到的消息,以字節方式進行傳輸
n?= connfd.send(b'adsfafef')
n為發送的字節數
功能:發送消息
參數buffersize:每次最多接收的消息大小 bytes
connfd.sent(b'hello woeld')返回值是發送的字節數
6、關閉套接字
close()
功能:關閉套接字,tcp連接斷開
telnet ip port? 表示連接tcp服務端
import socketsockfd = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 創建tcp套接字 sockfd.bind(('0.0.0.0', 8888)) # 綁定地址 sockfd.listen(5) # 設置監聽print("Waiting for connect...") # 阻塞等待處理連接 connfd, addr = sockfd.accept() # 等待客戶端連接 print("Connect from", addr) # 打印鏈接的客戶端地址 data = connfd.recv(1024) # 接收消息 print("收到:", data) n = connfd.send(b'over') # 發送字節串 print("發送%d字節" % n)# 關閉套接字 connfd.close() sockfd.close()
TCP客戶端(以字節串傳輸信息)
1.創建套接字
socket()
* 通信的兩端套接字類型相同
2. 發起連接
sockfd.connect(("IP地址",端口號))
功能 : 發起連接請求
參數 : 元組,服務器端的地址
3.發收消息
sockfd.send(字節串內容)
sockfd.recv() # 接收到的是字節串內容
* 兩端收發需要配合
4.關閉套接字
close()?
from socket import *sockfd = socket() # 創建套接字,TCP協議不用填寫缺省值 sockfd.connect(("176.122.1.61",8888)) # 發起請求連接IP地址176.122.1.61,端口8888的主機 data = input("發送:") # 輸入要發送的信息 sockfd.send(data.encode()) # 發送字節串內容 d = sockfd.recv(1024).decode() # 接收到的是字節串內容 print("接收到:", d) sockfd.close()?
UDP服務器
UDP是無連接的, 不用accetp和listen
1、創建套接字----》數據報套接字
sockfd = socket(AF_INET,SOCK_DGRAM)
2、綁定服務端地址
sockfd.bind()
3、消息的收發
data,addr = sockfd.recvfrom(buffersize)
功能:接收udp消息
參數:每次最多接受消息大小
返回值:data 接收到的消息 addr 消息發送者的地址(IP號和端口號)
sockfd.sendto(data,addr)
功能:udp發送消息
參數:data要發送的消息? bytes
addr 客戶端地址(地址包括IP和端口號)
返回值:發送的字節
每次接收一個報文,如果沒有接收完全則丟棄沒有收到的內容
4、關閉套接字
sockfd.close()
""" UDP 套接字服務端""" from socket import *sockfd = socket(AF_INET, SOCK_DGRAM) # 創建套接字 sockfd.bind(('127.0.0.1', 8888)) # 綁定地址# 收發消息 while True:data, addr = sockfd.recvfrom(1024)print("收到的消息:", data.decode())sockfd.sendto(b'Receive', addr)sockfd.close() # 關閉套接字
UDP客戶端
1、創建套接字
sockfd = socket(AF_INET,SOCK_DGRAN)
2、消息收發
收:data,addr = sockfd.recvfrom(buffersize)
發:sockfd.sendto(data,addr)
data,addr = sockfd.recvfrom(1024)
sockfd.sendto(data.encode(), ("192.168.191.3",8888))
3、關閉套接字
sockfd.close()
from socket import * import sys # 命令行輸入服務器地址 if len(sys.argv) < 3:print('''argv is error !!請在終端輸入python3 udp_client.py 127.0.0.1 8888''')raise HOST = sys.argv[1] PORT = int(sys.argv[2]) ADDR = (HOST,PORT)sockfd = socket(AF_INET,SOCK_DGRAM) # 創建套接字while True:data = input("消息:")if not data: # 如果收到空消息則退出breaksockfd.sendto(data.encode(),ADDR)data,addr = sockfd.recvfrom(1024)print("從服務端收到:",data.decode())sockfd.close()
補充:? sys.argv
功能:獲取來自命令行的參數,形成一個列表
以空格作為每一項分隔,如果一項中有空格則用引號表示一個整體
命令行內容作為字符串傳入
TCP流式套接字和UDP數據報套接字區別
1、流式套接字采用字節流的方式傳輸數據,而數據報套接字以數據報形式傳輸
2、TCP會產生粘包現象,UDP消息是有邊界的不會粘包
3、TCP傳輸是建立在連接的基礎上,保證傳輸的可靠性,而UDP一次接收一個數據報,不保證完整性
4、TCP需要依賴listen、accept建立連接,UDP不用
5、TCP收發消息使用recv、send、sendall。UDP使用recvfrom、sendto
UDP應用之廣播
一點發送多點接收
目標地址:廣播地址,每個網段類最大的地址
172.60.50.255 ----》<broadcast>
廣播接收
from socket import * s = socket(AF_INET,SOCK_DGRAM) # 創建一個數據報套接字 s.setsockopt(SOL_SOCKET,SO_BROADCAST,1) # 設置為可以接收廣播 s.bind(('0.0.0.0',9999)) # 綁定IP地址 while True:try:msg,addr = s.recvfrom(1024)print("從{}獲取信息:{}".format(addr,msg.decode()))except KeyboardInterrupt:print("接收消息結束")breakexcept Exception as e:print(e) s.close()
廣播發送
from socket import * from time import sleep dest = ('192.168.191.3',9999)# 設置廣播地址 s = socket(AF_INET,SOCK_DGRAM) # 創建一個數據報套接字 s.setsockopt(SOL_SOCKET,SO_BROADCAST,1) #設置套接字可以發送接受廣播 while True:sleep(1)s.sendto("我叫凌逆戰!".encode(),dest) s.close()
?