
套接字(Socket)
伯克利套接字(BSD Socket)
套接字(socket)是一個(gè)抽象層,應(yīng)用程序可以通過(guò)它發(fā)送或接收數(shù)據(jù),可對(duì)其進(jìn)行像對(duì)文件一樣的打開(kāi)、讀寫(xiě)和關(guān)閉等操作。套接字允許應(yīng)用程序?qū)/O插入到網(wǎng)絡(luò)中,并與網(wǎng)絡(luò)中的其他應(yīng)用程序進(jìn)行通信。網(wǎng)絡(luò)套接字是IP地址與端口的組合?!?度娘 建議看完度娘的介紹
根據(jù) RFC793的定義:端口號(hào)拼接到 IP地址就構(gòu)成了套接字。套接字 Socket=(IP地址:端口號(hào))
套接字分類
流式套接字(
SOCK-STREAM)、數(shù)據(jù)報(bào)套接字(SOCK-DGRAM)、原始套接字(SOCK-RAW)
- 流式套接字(
SOCK-STREAM):使用TCP協(xié)議來(lái)實(shí)現(xiàn)字節(jié)流的傳輸 * - 數(shù)據(jù)報(bào)套接字(
SOCK-DGRAM):使用UDP協(xié)議來(lái)實(shí)現(xiàn)數(shù)據(jù)報(bào)套接字 * - 原始套接字(
SOCK-RAW):該套接字允許對(duì)較低層協(xié)議(如 IP或 ICMP)進(jìn)行直接訪問(wèn),常用于網(wǎng)絡(luò)協(xié)議分析,檢驗(yàn)新的網(wǎng)絡(luò)協(xié)議實(shí)現(xiàn),也可用于測(cè)試新配置或安裝的網(wǎng)絡(luò)設(shè)備 [網(wǎng)絡(luò)層的原始協(xié)議]
python Socket
套接字協(xié)議族
-
AF_UNIX:一個(gè)綁定在文件系統(tǒng)節(jié)點(diǎn)上的字符串 -
AF_INET:一對(duì)(host, port)—— IPv4 -
AF_INET6:使用一個(gè)四元組(host, port, flowinfo, scopeid)—— IPv6 -
AF_NETLINKsockets are represented as pairs(pid, groups) AF_TIPC-
AF_CAN:A tuple (interface, ) 。其中 interface是代表網(wǎng)絡(luò)接口名稱(如“ can0”)的字符串 PF_SYSTEM-
AF_BLUETOOTH:藍(lán)牙相關(guān) AF_ALG-
AF_VSOCK:允許虛擬機(jī)與其主機(jī)之間的通信 -
AF_PACKET:直接連接網(wǎng)絡(luò)設(shè)備的底層接口
NOTE: 套接字地址在實(shí)際的 IPv4/v6 中以不同方式解析,如果你在 IPv4/v6 套接字地址的 host 部分中使用了一個(gè)主機(jī)名,此程序可能會(huì)表現(xiàn)不確定行為
模塊內(nèi)容
異常:
-
exception socket.error
OSError的別名 -
exception socket.herror
它針對(duì)的是與地址相關(guān)的錯(cuò)誤 -
xception socket.gaierror
getaddrinfo()和getnameinfo()針對(duì)與地址相關(guān)的錯(cuò)誤引發(fā)此異常 -
exception socket.timeout
發(fā)生超時(shí)時(shí)拋出
常量:
socket.AF_UNIXsocket.AF_INETsocket.AF_INET6
這些常量表示 地址(和協(xié)議) 族,用于 socket() 的 第一個(gè)參數(shù)。 如果 未定義 AF_UNIX常量,則不支持此協(xié)議。 根據(jù)系統(tǒng),可能會(huì)有更多的常量可用。
-
socket.SOCK_STREAM—— TCP -
socket.SOCK_DGRAM—— UDP socket.SOCK_RAWsocket.SOCK_RDMsocket.SOCK_SEQPACKET
這些常量表示 套接字類型,用于 socket() 的 第二個(gè)參數(shù)。根據(jù)系統(tǒng)的不同,可以使用更多的常量。(一般來(lái)說(shuō),只有 SOCK STREAM和 SOCK DGRAM是有用的。)
socket.SOCK_CLOEXECsocket.SOCK_NONBLOCK
如果定義了這兩個(gè)常量,就可以與 套接字類型 結(jié)合使用,并允許您自動(dòng)設(shè)置一些標(biāo)志(從而避免可能的競(jìng)爭(zhēng)條件和需要單獨(dú)調(diào)用)。
函數(shù)
Creating sockets
以下函數(shù)都創(chuàng)建 socket對(duì)象
-
socket.socket(family=AF_INET, type=SOCK_STREAM, proto=0, fileno=None)!使用給定的 地址族,套接字類型和協(xié)議號(hào)創(chuàng)建一個(gè)新的套接字。 地址族應(yīng)為
AF_INET(默認(rèn)設(shè)置),AF_INET6,AF_UNIX,AF_CAN,AF_PACKET或AF_RDS。套接字類型 應(yīng)為
SOCK_STREAM(默認(rèn)值),SOCK_DGRAM,SOCK_RAW或其他SOCK_常量之一。協(xié)議號(hào)通常為零,可以省略,或者在地址族為
AF_CAN的情況下,協(xié)議應(yīng)為CAN_RAW,CAN_BCM或CAN_ISOTP之一如果指定了
fileno,則將從指定的文件描述符中自動(dòng)檢測(cè)family,type和proto的值。
通過(guò)使用 顯式族,類型或原型參數(shù)調(diào)用該函數(shù),可以關(guān)閉自動(dòng)檢測(cè)。 這只會(huì)影響 Python的表示方式socket.getpeername()的返回值,而不是實(shí)際的操作系統(tǒng)資源。 與socket.fromfd()不同,fileno將返回相同的套接字,而不是重復(fù)的套接字。 這可能有助于使用socket.close()關(guān)閉分離的套接字。新創(chuàng)建的套接字是不可繼承的
-
socket.socketpair([family[, type[, proto]]])使用給定的地址族,套接字類型和協(xié)議號(hào)構(gòu)建一對(duì)連接的套接字對(duì)象。
地址族,套接字類型和協(xié)議號(hào)與上面的socket()函數(shù)相同。
如果在平臺(tái)上定義,則默認(rèn)系列為AF_UNIX。 否則,默認(rèn)值為AF_INET新創(chuàng)建的套接字是不可繼承的
-
socket.create_connection(address[, timeout[, source_address]])連接到偵聽(tīng) Internet地址(一個(gè) 2元組
(host, port))的 TCP服務(wù),然后返回套接字對(duì)象。這是比
socket.connect()更高級(jí)別的函數(shù):如果 host是 非數(shù)字主機(jī)名,它會(huì)嘗試同時(shí)為AF_INET和AF_INET6解析它,然后嘗試依次連接到所有可能的地址,直到連接成功 。這使得編寫(xiě)兼容 IPv4和 IPv6的客戶端變得容易
傳遞可選超時(shí)參數(shù)將在嘗試連接之前設(shè)置套接字實(shí)例的超時(shí)。如果未提供超時(shí),將使用
getdefaulttimeout()返回的全局默認(rèn)超時(shí)設(shè)置。如果提供源地址,則
source_address必須為 2元組(host, port),以便套接字在連接之前綁定為其源地址。 如果主機(jī)或端口分別為 ' ' 或 0,則將使用操作系統(tǒng)默認(rèn)行為 socket.fromfd(fd, family, type, proto=0)socket.fromshare(data)(可用性:Windows)-
socket.SocketType表示套接字對(duì)象類型的 Python類型對(duì)象。 它與
type(socket(...))相同
其他功能
socket模塊還提供各種網(wǎng)絡(luò)相關(guān)服務(wù)
socket.close(fd)-
socket.getaddrinfo(host, port, family=0, type=0, proto=0, flags=0)將 主機(jī)/端口 參數(shù)轉(zhuǎn)換為 5元組的序列,其中包含用于創(chuàng)建連接到該服務(wù)的套接字的所有必需參數(shù)。 host是域名,IPv4/v6地址以字符串或 None的形式表示 。 port是字符串服務(wù)名稱,例如 " http",數(shù)字端口號(hào)或 "None"。 通過(guò)將 None用作主機(jī)和端口的值,可以將 NULL傳遞給基礎(chǔ) C API
該函數(shù)返回具有以下結(jié)構(gòu)的 5元組列表:
(family, type, proto, canonname, sockaddr)在這些元組中,
family、type、proto都是整數(shù),都要傳遞給socket()函數(shù)。如果AI_CANONNAME是flags參數(shù)的一部分,那么canonname將是一個(gè)表示主機(jī)的規(guī)范名稱的字符串;否則,canonname將為空。sockaddr是一個(gè)描述套接字地址的元組,它的格式依賴于返回的返回的族(對(duì)于AF_INET,是一個(gè)(address, port)2元組,對(duì)于AF_INET6是一個(gè)(address, port, flow info, scope id),并被傳遞給socket.connect()方法s2 = socket.getaddrinfo(host_IP, host_port, socket.AF_INET, socket.SOCK_STREAM) print(s2) [(2, 1, 6, '', ('172.17.0.2', 1124))] -
socket.getfqdn([name])返回名稱的完全限定域名。 如果 name省略或?yàn)榭眨瑒t將其解釋為本地主機(jī)
如果沒(méi)有完全限定的域名可用,則返回由gethostname()返回的主機(jī)名 -
socket.gethostbyname(hostname)將主機(jī)名轉(zhuǎn)換為 IPv4地址格式,如果主機(jī)名本身是一個(gè) IPv4地址,它將原封不動(dòng)地返回
-
socket.gethostbyname_ex(hostname)將主機(jī)名轉(zhuǎn)換為 IPv4地址格式的擴(kuò)展接口。 返回一個(gè)三元組
(hostname, aliaslist, ipaddrlist)s4 = socket.gethostbyname_ex(socket.gethostname()) print(s4) ('c6f1ab98bb5f', [], ['172.17.0.2']) socket.gethostname()-
socket.gethostbyaddr(ip_address)Return a triple
(hostname, aliaslist, ipaddrlist) -
socket.getnameinfo(sockaddr, flags)將套接字地址
sockaddr轉(zhuǎn)換為2元組(host, port)。根據(jù)標(biāo)志的設(shè)置,結(jié)果可以包含主機(jī)中完全限定的域名或數(shù)字地址表示。類似地,端口可以包含字符串端口名或數(shù)字端口號(hào) socket.getprotobyname(protocolname)socket.getservbyname(servicename[, protocolname])socket.getservbyport(port[, protocolname])socket.inet_aton(ip_string)socket.inet_ntoa(packed_ip)socket.inet_pton(address_family, ip_string)socket.inet_ntop(address_family, packed_ip)socket.CMSG_LEN(length)socket.CMSG_SPACE(length)-
socket.getdefaulttimeout()為新的套接字對(duì)象返回默認(rèn)超時(shí)(以秒為單位)。None值表示新的套接字對(duì)象沒(méi)有超時(shí)。當(dāng)?shù)谝淮螌?dǎo)入套接字模塊時(shí),默認(rèn)為 None
socket.setdefaulttimeout(timeout)
設(shè)置新的套接字對(duì)象的默認(rèn)超時(shí)時(shí)間(以秒為單位)(浮點(diǎn)數(shù))-
socket.sethostname(name)將機(jī)器的主機(jī)名設(shè)置為 name。 如果您沒(méi)有足夠的權(quán)限,則會(huì)引發(fā) OSError
-
socket.if_nameindex()返回網(wǎng)絡(luò)接口信息 (index int, name string) 元組的列表。 如果系統(tǒng)調(diào)用失敗,則發(fā)生OSError
socket.if_nametoindex(if_name)socket.if_indextoname(if_index)
Socket Objects
套接字對(duì)象具有以下方法。 除了 makefile() 以外,它們對(duì)應(yīng)于適用于套接字的 Unix系統(tǒng)調(diào)用
-
socket.accept()—— Server接受連接。 套接字必須綁定到一個(gè)地址并監(jiān)聽(tīng)連接。 返回值是一對(duì)
(conn,address),其中conn是可用于在連接上發(fā)送和接收數(shù)據(jù)的新套接字對(duì)象,而address是在連接另一端綁定到套接字的地址 -
socket.bind(address)—— Server將套接字綁定到地址
socket.close()-
socket.connect(address)—— Client按地址連接到遠(yuǎn)程套接字
-
socket.connect_ex(address)與
connect(address)類似,但返回錯(cuò)誤指示符而不是針對(duì)C級(jí)connect()調(diào)用返回的錯(cuò)誤引發(fā)異常(其他問(wèn)題,例如“找不到主機(jī)”仍然可以引發(fā)異常)。 如果操作成功,則錯(cuò)誤指示符為0,否則為errno變量的值。 這對(duì)于支持例如 異步連接 很有用 -
socket.detach()將套接字對(duì)象置于關(guān)閉狀態(tài),而不實(shí)際關(guān)閉底層文件描述符。返回文件描述符,并且可以將其重新用于其他目的
-
socket.dup()復(fù)制套接字
-
socket.fileno()返回套接字的文件描述符(一個(gè)小整數(shù)),如果失敗則返回 -1。這對(duì)于
select.select()非常有用 socket.get_inheritable()socket.getpeername(): 返回套接字連接到的遠(yuǎn)程地址socket.getsockname():返回套接字自己的地址socket.getsockopt(level, optname[, buflen])-
socket.getblocking()如果套接字處于阻塞模式,則返回 True;如果處于非阻塞模式,則返回 False
socket.gettimeout()socket.ioctl(control, option)-
socket.listen([backlog])—— Server使服務(wù)器能夠接受連接。如果指定了backlog,則它必須至少為 0(如果它更低,則設(shè)置為0);它指定系統(tǒng)在拒絕新連接之前允許的未接受連接的數(shù)量。如果未指定,則選擇默認(rèn)的合理值
-
socket.makefile(mode='r', buffering=None, *, encoding=None, errors=None, newline=None)返回與套接字關(guān)聯(lián)的文件對(duì)象
-
socket.recv(bufsize[, flags])從套接字接收數(shù)據(jù)。返回值是一個(gè)字節(jié)對(duì)象,表示接收到的數(shù)據(jù)
-
socket.recvfrom(bufsize[, flags])從套接字接收數(shù)據(jù)。 返回值是一對(duì)(字節(jié),地址),其中字節(jié)是代表接收到的數(shù)據(jù)的字節(jié)對(duì)象,而地址是發(fā)送數(shù)據(jù)的套接字的地址
-
socket.recvmsg(bufsize[, ancbufsize[, flags]])從套接字接收普通數(shù)據(jù)(最多bufsize字節(jié))和輔助數(shù)據(jù)
socket.recvmsg_into(buffers[, ancbufsize[, flags]])socket.recvfrom_into(buffer[, nbytes[, flags]])socket.recv_into(buffer[, nbytes[, flags]])-
socket.send(bytes[, flags])向套接字發(fā)送數(shù)據(jù)。返回發(fā)送的字節(jié)數(shù)。應(yīng)用程序負(fù)責(zé)檢查所有數(shù)據(jù)是否已經(jīng)發(fā)送;如果只傳輸了部分?jǐn)?shù)據(jù),應(yīng)用程序需要嘗試傳遞剩余的數(shù)據(jù)
-
socket.sendall(bytes[, flags])將數(shù)據(jù)發(fā)送到套接字。與
send()不同,此方法繼續(xù)從字節(jié)發(fā)送數(shù)據(jù),直到所有數(shù)據(jù)都已發(fā)送或發(fā)生錯(cuò)誤為止。 -
socket.sendto(bytes, flags, address)向套接字發(fā)送數(shù)據(jù)。套接字不應(yīng)連接到遠(yuǎn)程套接字,因?yàn)槟繕?biāo)套接字是由地址指定的
-
socket.sendmsg(buffers[, ancdata[, flags[, address]]])將普通數(shù)據(jù)和輔助數(shù)據(jù)發(fā)送到套接字,從一系列緩沖區(qū)中收集非輔助數(shù)據(jù),并將其串聯(lián)為一條消息
socket.sendmsg_afalg([msg, ]*, op[, iv[, assoclen[, flags]]])-
socket.sendfile(file, offset=0, count=None)使用高性能的
os.sendfile發(fā)送文件,直到達(dá)到EOF為止,并返回已發(fā)送的字節(jié)總數(shù)。
文件必須是以二進(jìn)制模式打開(kāi)的常規(guī)文件對(duì)象。 如果os.sendfile不可用(例如Windows)或文件不是常規(guī)文件,將使用send()代替。offset告訴您從哪里開(kāi)始讀取文件。
如果指定,count是要發(fā)送的字節(jié)總數(shù),而不是發(fā)送文件直到達(dá)到EOF。 返回時(shí)或發(fā)生錯(cuò)誤時(shí),文件位置將更新,在這種情況下,file.tell()可用于確定已發(fā)送的字節(jié)數(shù)。 套接字必須為SOCK_STREAM類型。 不支持非阻塞套接字 socket.set_inheritable(inheritable)-
socket.setblocking(flag)設(shè)置套接字的阻塞或非阻塞模式:如果 flag為 false,則將套接字設(shè)置為非阻塞,否則設(shè)置為阻塞模式
-
socket.settimeout(value)設(shè)置阻塞套接字操作的超時(shí)。值參數(shù)可以是表示秒的非負(fù)浮點(diǎn)數(shù),也可以是None。
如果給定 0,則套接字將處于非阻塞模式。如果沒(méi)有給出,套接字將進(jìn)入阻塞模式 socket.setsockopt(level, optname, None, optlen: int)socket.shutdown(how)-
socket.share(process_id)復(fù)制套接字,并準(zhǔn)備將其與目標(biāo)進(jìn)程共享。 目標(biāo)進(jìn)程必須提供有
process_id
Ex
