一、Socket編程概述
python中提供socket.py標準庫,非常底層的接口庫。socker是一種通用的網絡編程接口,和網絡層次沒有一一對應的關係。
socket可以跨操作系統,適合於任何類型的操作系統。
socket支持TCP與UDP協議。
服務的端口是由“進程”管理的,而不是由“線程”管理。
socket的定位?
socket是應用層與傳輸層之間的橋樑。
1個socket會佔用一個文件描述符。fd=13
1、約定協議族:AF,用於socket()第一個參數
AF_INET--->IPV4
AF_INET6--->IPV6
2、socket類型
sock_STREAM-->TCP協議
sock_DGRAM-->UDP協議
3、TCP編程
服務器端:socket()->bind(ip,port)->listen()->accept(阻塞等待客戶端連接,重新分配1個新的socket)->recvie()->send()-recvie()->close()
accept:允許接受請求,創建一系列新的socket連接。
客戶端:socket()->connect()->send()-recvie()->close()
accept和recv都是阻塞的。主線程經常被阻塞而不能工作。
4、關鍵方法的說明
socket.recv(bufsize):獲取數據。默認是阻塞的方式。
socket.recvfrom(bufsize):獲取數據,返回一個二元組。
socket.recv_into(buffer):返回接收數據的字節數,如果沒有就指定爲0
socket.recvfrom_into(buffer):返回一個二元組(bytes,address)到buffer中去。
socket.send(bytes):TCP發送數據
socket.sendall(bytes):TCP發送全部數據,成功返回None
s.sendto(string,address):UDP發送數據
socket.sendfile(file,offset=0,count=None):發送一個文件直到EOF,使用高性能的os.sendfile機制,返回發送的字節數。
二、server端代碼
from socket import * from time import ctime HOST = "127.0.0.1" PORT = 21000 BUFSIZE = 1024 #發送數據的緩衝區 ADDR = (HOST,PORT) tcpSerSock = socket(AF_INET,SOCK_STREAM) #此處用常用的AF_INET[ipv4],第二個參數是流套接字,即TCP tcpSerSock.bind(ADDR) #套接字與地址綁定 tcpSerSock.listen(5) #開始監聽,參數表示允許的最大連接數 while True: print('waiting for connection...') tcpCliSock,addr = tcpSerSock.accept() #接客,accept返回一個二元組(connection,address),第一個新的socket對象,服務器必須通過它與客戶通信;第二個是客戶的地址。 print('...connnecting from:',addr) while True: data = tcpCliSock.recv(BUFSIZE) #接收數據,把話記錄到data中。 if not data: #接收完畢,退出。 break tcpCliSock.send(('[%s] %s' % (ctime(), data)).encode()) #發送當前時間,以及數據給客人 tcpCliSock.close() #關閉與該客人通信的套接字。 tcpSerSock.close() #因爲上面是死循環,此處不是必須的,只是提醒大家離開的時候務必要關門
三、client端代碼
from socket import * HOST = '127.0.0.1' #因爲我是在同一臺機器上運行,所以是localhost,不同主機的話,此處需要改成服務器地址 PORT = 21000 BUFSIZ =1024 ADDR = (HOST,PORT) tcpCliSock = socket(AF_INET,SOCK_STREAM) #客戶端只需要一個套接字 tcpCliSock.connect(ADDR) #發起連接 while True: data1 = input('>') if not data1: #數據發送完畢,關閉。 break tcpCliSock.send(data1.encode()) #發送數據 data1 = tcpCliSock.recv(BUFSIZ) #接收數據 if not data1: break print(data1.decode('utf-8')) tcpCliSock.close()