socket是什么
什么是socket所謂socket通常也稱作"套接字",用于描述IP地址和端口猬错,是一個(gè)通信鏈的句柄。應(yīng)用程序通常通過"套接字"向網(wǎng)絡(luò)發(fā)出請(qǐng)求或者應(yīng)答網(wǎng)絡(luò)請(qǐng)求絮识。說白了就是一種通信機(jī)制礁苗。它類似于銀行,電信啊這些部分的電話客服部門级解。你打電話的時(shí)候冒黑,那邊會(huì)分配置一個(gè)人回答你的問題,客服部門就相當(dāng)于socket的服務(wù)器端了勤哗,你這邊呢就相當(dāng)于客戶端了抡爹,在和你通話結(jié)束前,如果有人在想找和你通話的那個(gè)說話芒划,是不可能的冬竟,因?yàn)槟阍诤退ㄐ排费ǎ?dāng)然客服部門的電話交換機(jī)也不會(huì)重復(fù)分配。我們天天用的http\smtp\ftp等網(wǎng)絡(luò)協(xié)議都是基于socket的上層實(shí)現(xiàn)泵殴,無論使用何種網(wǎng)絡(luò)協(xié)議涮帘,最本質(zhì)上都是在進(jìn)行數(shù)據(jù)的接收和發(fā)送,只不過發(fā)送的數(shù)據(jù)類型和內(nèi)容不同罷了笑诅,“發(fā)送”和“接收”這兩個(gè)動(dòng)作就是socket處理數(shù)據(jù)的主要方式调缨。
socket起源于Unix,而Unix/Linux基本哲學(xué)之一就是“一切皆文件”吆你,都可以用“打開open–> 讀寫write/read–> 關(guān)閉close”模式來操作弦叶。Socket就是該模式的一個(gè)實(shí)現(xiàn),socket即是一種特殊的文件妇多,一些socket函數(shù)就是對(duì)其進(jìn)行的操作(讀/寫IO伤哺、打開、關(guān)閉)者祖,python的socket模塊是直接調(diào)用的unix的socket庫立莉,接下來我們一起來看下,如何在python下實(shí)現(xiàn)socket咸包。
使用socket時(shí)需要指定Socket Family(地址簇)桃序,包括以下幾種:
- socket.AF_UNIX 只能夠用于單一的Unix系統(tǒng)進(jìn)程間通信
- socket.AF_INET 用于主機(jī)之間的網(wǎng)絡(luò)通信
- socket.AF_INET6 IPv6通信
若想實(shí)現(xiàn)主機(jī)之間的通信,我們就得使用socket.AF_INET
確認(rèn)地址簇后烂瘫,還需要指定socket 數(shù)據(jù)類型
- socket.SOCK_STREAM 流式socket, for TCP
- socket.SOCK_DGRAM 數(shù)據(jù)報(bào)式socket, for UDP
- socket.SOCK_RAW 原始套接字媒熊,普通的套接字無法處理ICMP、IGMP等網(wǎng)絡(luò)報(bào)文坟比,而SOCK_RAW可以芦鳍;其次,SOCK_RAW也可以處理特殊的IPv4報(bào)文葛账;此外柠衅,利用原始套接字,可以通過IP_HDRINCL套接字選項(xiàng)由用戶構(gòu)造IP頭籍琳。
- socket.SOCK_RDM 是一種可靠的UDP形式菲宴,即保證交付數(shù)據(jù)報(bào)但不保證順序。SOCK_RAM用來提供對(duì)原始協(xié)議的低級(jí)訪問趋急,在需要執(zhí)行某些特殊操作時(shí)使用喝峦,如發(fā)送ICMP報(bào)文。SOCK_RAM通常僅限于高級(jí)用戶或管理員運(yùn)行的程序使用呜达。
- socket.SOCK_SEQPACKET 可靠的連續(xù)數(shù)據(jù)包服務(wù)
我們主要用的一般是SOCK_STREAM (for TCP)和SOCK_DGRAM(for UDP)
進(jìn)行socket調(diào)用時(shí)可能會(huì)用到的函數(shù):
- s = socket(family,type[,protocal]) 使用給定的地址族谣蠢、套接字類型、協(xié)議編號(hào)(默認(rèn)為0)來創(chuàng)建套接字。
套接字的實(shí)例具有以下方法:
- s.bind(address) 將套接字綁定到地址眉踱。address地址的格式取決于地址族挤忙。在AF_INET下,以元組(host,port)的形式表示地址谈喳。
- s.listen(backlog) 開始監(jiān)聽傳入連接册烈。backlog指定在拒絕連接之前,操作系統(tǒng)可以掛起的最大連接數(shù)量叁执。該值至少為1茄厘,大部分應(yīng)用程序設(shè)為5就可以了矮冬。
- s.connect(address) 連接到address處的套接字谈宛。一般,address的格式為元組(hostname,port)胎署,如果連接同一臺(tái)機(jī)器上的服務(wù)器吆录,可以將hostname設(shè)為‘localhost’。如果連接出錯(cuò)琼牧,返回socket.error錯(cuò)誤恢筝。
- s.connect_ex(adddress) 功能與connect(address)相同,但是成功返回0巨坊,失敗返回errno的值撬槽。
- s.accept() 接受連接并返回(conn,address),其中conn是新的套接字對(duì)象,可以用來接收和發(fā)送數(shù)據(jù)趾撵。address是連接客戶端的地址侄柔。
- s.close() 關(guān)閉套接字。
- s.fileno() 返回套接字的文件描述符占调。
- s.getpeername() 返回連接套接字的遠(yuǎn)程地址暂题。返回值通常是元組(ipaddr,port)。
- s.getsockname() 返回套接字自己的地址究珊。通常是一個(gè)元組(ipaddr,port)
- s.getsockopt(level,optname[.buflen]) 返回套接字選項(xiàng)的值薪者。
- s.gettimeout() 返回當(dāng)前超時(shí)期的值,單位是秒剿涮,如果沒有設(shè)置超時(shí)期言津,則返回None。
- s.recv(bufsize[,flag]) 接受套接字的數(shù)據(jù)取试。數(shù)據(jù)以字符串形式返回悬槽,bufsize指定要接收的最大數(shù)據(jù)量。flag提供有關(guān)消息的其他信息想括,通诚萜祝可以忽略。
- s.recvfrom(bufsize[.flag]) 與recv()類似,但返回值是(data,address)烟逊。其中data是包含接收數(shù)據(jù)的字符串渣窜,address是發(fā)送數(shù)據(jù)的套接字地址。
- s.send(string[,flag]) 將string中的數(shù)據(jù)發(fā)送到連接的套接字宪躯。返回值是要發(fā)送的字節(jié)數(shù)量乔宿,該數(shù)量可能小于string的字節(jié)大小。
- s.sendall(string[,flag]) 將string中的數(shù)據(jù)發(fā)送到連接的套接字访雪,但在返回之前會(huì)嘗試發(fā)送所有數(shù)據(jù)详瑞。成功返回None,失敗則拋出異常臣缀。
- s.sendto(string[,flag],address) 將數(shù)據(jù)發(fā)送到套接字坝橡,address是形式為(ipaddr,port)的元組精置,指定遠(yuǎn)程地址计寇。返回值是發(fā)送的字節(jié)數(shù)。該函數(shù)主要用于UDP協(xié)議脂倦。
- s.setblocking(flag) 如果flag為0番宁,則將套接字設(shè)為非阻塞模式,否則將套接字設(shè)為阻塞模式(默認(rèn)值)赖阻。非阻塞模式下蝶押,如果調(diào)用recv()沒有發(fā)現(xiàn)任何數(shù)據(jù),或send()調(diào)用無法立即發(fā)送數(shù)據(jù)火欧,那么將引起socket.error異常棋电。
- s.setsockopt(level,optname,value) 設(shè)置給定套接字選項(xiàng)的值。
- s.settimeout(timeout) 設(shè)置套接字操作的超時(shí)期布隔,timeout是一個(gè)浮點(diǎn)數(shù)离陶,單位是秒。值為None表示沒有超時(shí)期衅檀。一般招刨,超時(shí)期應(yīng)該在剛創(chuàng)建套接字時(shí)設(shè)置,因?yàn)樗鼈兛赡苡糜谶B接的操作(如connect())普通的非套接字實(shí)例的函數(shù)
- getdefaulttimeout()返回默認(rèn)的套接字超時(shí)時(shí)間(以秒為單位)哀军。None表示不設(shè)置任何超時(shí)時(shí)間沉眶。
- gethostbyname(hostname) 將主機(jī)名(如“www.baidu.com”)轉(zhuǎn)換為IPv4地址,IP地址將以字符串的形式返回杉适,如“8.8.8.8”谎倔。不支持IPv6
- gethostname() 返回本地機(jī)器的主機(jī)名。