socket
socket一般也稱做"套接字",用於描述IP地址和端口,應用程序一般經過"套接字"向網絡發出請求或者應答網絡請求,能夠認爲是一種計算機網絡的數據結構,接口。它是網絡編程的基礎html
套接字最先起源於Unix系統,一開始使用與一臺電腦之間的進程間通信,目前套接字分爲兩種,基於文件型和基於網絡型。其中一臺主機的進程間是經過基於文件的套接字進行通信(AF_UNIX或者AF_LOCAL)。而還有一種基於網絡的,可用於不一樣主機之間的通訊(AF_INET和AP_INET6),AF_INET是用於IPV4,而AF_INET6是用於IPV6。python
套接字還分爲面向鏈接的和無鏈接的:編程
- 第一種是指TCP類型套接字,在通訊前須要創建鏈接,這種鏈接是較爲可靠的,使用的套接字類型是SOCK_STREAM,TCP傳輸控制協議,常常和IP協議一塊兒使用,稱爲TCP/IP協議
- 第二種主要指UDP類型的套接字,無需鏈接就能夠進行通信,全部速度較快,可是可靠性不高。並且數據是整個發送,不會分紅小塊。使用的套接字類型是SOCK_DGRAM,UDP協議一般也與IP協議一塊兒使用
python中的socket模塊
使用套接字的基本步驟:服務器
-
建立套接字markdown
socket(socket_family, socket_type, protocol) #socket_family 就是指套接字家族能夠是AF_VNIX或AF_INET #socket_type 就是指套接字類型,即SOCK_STREAM或SOCK_DGRAM #protocol 是協議,默認爲0,通常不填
- 建立TCP/IP或者UDP/IP套接字
-
建立TCP/IP套接字網絡
import socket tcp = socket.socket(AF_INET, SOCK_STREAM)
-
建立UDP/IP套接字數據結構
import socket ucp = socket.socket(AF_INET, SOCK_DGRAM)
-
-
套接字的經常使用函數併發
函數名 | 描述 |
---|---|
服務器套接字 | |
bind((hostname, port)) | 綁定地址(注意這裏是元祖)到套接字 |
listen() | 開啓TCP監聽 |
accept() | 被動接受客戶端的鏈接(阻塞) |
客戶端套接字 | |
connect((hostname, port)) | 初始化TCP服務器鏈接 |
connect_ex() | connect()的擴展版本,出錯時返回錯誤碼,而不是異常 |
公用的套接字 | |
recv() | 接收TCP的數據 |
send() | 發送TCP數據 |
sendall() | 發送完整的TCP數據 |
recvfrom() | 接收UDP數據 |
sendto() | 發生UDP數據,由於沒有鏈接,因此這裏要指定發送的目標 |
getpeername() | 鏈接到當前套接字的遠程地址 |
getsockname() | 當前socket地址 |
getsockopt() | 得到套接字的參數 |
setsockopt() | 設置套接字的參數 |
close() | 關閉套接字 |
面向模塊的套接字函數 | |
setblocking() | 設置套接字是不是阻塞模式 |
settimeout() | 設置阻塞套接字操做的超時時間 |
gettimeout() | 獲得阻塞套接字操做的超時時間 |
面向文件的套接字函數 | |
fileno() | 套接字的文件描述符 |
makefile() | 建立一個與套接字關聯的文件對象 |
建立一個TCP服務器和客戶端
建立TCP服務器的基本步驟socket
- 建立套接字並綁定地址
- 開始監聽鏈接
- 接收連接併發送數據
- 關閉套接字
代碼以下:tcp
import socket HOST = '' #空字符串標示127.0.0.1 PORT = 3214 sk = socket.socket() # 默認使用IPV4和TCP sk.bind((HOST,PORT)) sk.listen(5) cli, addr = sk.accept() # 等待鏈接(阻塞式),在鏈接到來以前會阻塞在這裏 print "Client Addr:", addr while True: data = cli.recv(1024) if not data: break print "Recieve Data:", data.decode('utf-8') cli.send(data) cli.close()
建立TCP客戶端的基本步驟
- 建立套接字,鏈接服務器
- 收發數據
- 關閉套接字
import socket HOST = '127.0.0.1' PORT = 3214 sk = socket.socket() try: sk.connect((HOST, PORT)) data = "hello" while data: sk.sendall(data) data = sk.recv(1024) print "Recv data:", data data = raw_input('Please input message\n') except socket.error as err: print err finally: sk.close()
這裏的客戶端僅僅能夠用來發送消息給服務端,而服務端會接收消息而後從新發送回客戶端
建立UDP服務器和客戶端
建立UDP服務端的基本步驟
- 建立套接字並綁定地址
- 開始監聽鏈接
- 收發數據
- 關閉套接字
import socket HOST = '' PORT = 3214 sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sk.bind((HOST, PORT)) data = True while data: data, addr = sk.recvfrom(1024) if data == b'bye': break print "Recieve Data:", data.decode('utf-8') sk.sendto(data, addr) sk.close()
建立UDP客戶端的基本步驟
- 建立套接字
- 收發數據
- 關閉套接字
import socket HOST = '127.0.0.1' PORT = 3214 sk = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) data = 'hello' while data: sk.sendto(data, (HOST, PORT)) if data == "bye": break data, addr = sk.recvfrom(1024) print "Recv Data:", data data = raw_input('Please message:\n') sk.close() # tcpclient與udpclient區別 # 創建socket時的區別 # tcp須要連接服務端 # 收發數據方法不一樣
這裏與TCP的區別就是不用創建鏈接,客戶端只是收發消息,並不會與服務器創建鏈接