socket是網(wǎng)絡(luò)連接端點(diǎn)。例如當(dāng)你的Web瀏覽器請(qǐng)求ansheng.me的網(wǎng)站時(shí),你的Web瀏覽器創(chuàng)建一個(gè)socket并命令它去連接ansheng.me的Web服務(wù)器主機(jī),Web服務(wù)器也對(duì)過來的請(qǐng)求在一個(gè)socket上進(jìn)行監(jiān)聽。兩端使用各自的socket來發(fā)送和接收信息。
在使用的時(shí)候,每個(gè)socket都被綁定到一個(gè)特定的IP地址和端口。IP地址是一個(gè)由4個(gè)數(shù)組成的序列,這4個(gè)數(shù)均是范圍0~255中的值;端口數(shù)值的取值范圍是0~65535。端口數(shù)小于1024的都是為眾所周知的網(wǎng)絡(luò)服務(wù)所保留的;最大的保留數(shù)被存儲(chǔ)在socket模塊的IPPORT_RESERVED變量中。
不是所有的IP地址都對(duì)世界的其它地方可見。實(shí)際上,一些是專門為那些非公共的地址所保留的(比如形如192.168.y.z或10.x.y.z)。地址127.0.0.1是本機(jī)地址;它始終指向當(dāng)前的計(jì)算機(jī)。程序可以使用這個(gè)地址來連接運(yùn)行在同一計(jì)算機(jī)上的其它程序。
IP地址不好記,你可以花點(diǎn)錢為特定的IP地址注冊(cè)一個(gè)主機(jī)名或域名。域名服務(wù)器(DNS)處理名字到IP地址的映射。每個(gè)計(jì)算機(jī)都可以有一個(gè)主機(jī)名,即使它沒有在官方注冊(cè)。
Python 提供了兩個(gè)基本的 socket 模塊。
第一個(gè)是 Socket,它提供了標(biāo)準(zhǔn)的 BSD Sockets API。
第二個(gè)是 SocketServer, 它提供了服務(wù)器中心類,可以簡化網(wǎng)絡(luò)服務(wù)器的開發(fā)。
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
參數(shù)一:地址簇
參數(shù) | 描述 |
---|---|
socket.AF_INET | IPv4(默認(rèn)) |
socket.AF_INET6 | IPv6 |
ocket.AF_UNIX | 只能夠用于單一的Unix系統(tǒng)進(jìn)程間通信 |
參數(shù)二:類型
參數(shù) | 描述 |
---|---|
socket.SOCK_STREAM | 流式socket , for TCP (默認(rèn)) |
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ù) |
參數(shù)三:協(xié)議
參數(shù) | 描述 |
---|---|
0 | (默認(rèn))與特定的地址家族相關(guān)的協(xié)議,如果是 0 ,則系統(tǒng)就會(huì)根據(jù)地址格式和套接類別,自動(dòng)選擇一個(gè)合適的協(xié)議 |
方法 | 描述 |
---|---|
s.bind(address) | 將套接字綁定到地址。address地址的格式取決于地址族。在AF_INET下,以元組(host,port)的形式表示地址。 |
sk.listen(backlog) | 開始監(jiān)聽傳入連接。backlog指定在拒絕連接之前,可以掛起的最大連接數(shù)量。 |
sk.setblocking(bool) | 是否阻塞(默認(rèn)True),如果設(shè)置False,那么accept和recv時(shí)一旦無數(shù)據(jù),則報(bào)錯(cuò)。 |
sk.accept() | 接受連接并返回(conn,address),其中conn是新的套接字對(duì)象,可以用來接收和發(fā)送數(shù)據(jù)。address是連接客戶端的地址。 |
sk.connect(address) | 連接到address處的套接字。一般,address的格式為元組(hostname,port),如果連接出錯(cuò),返回socket.error錯(cuò)誤。 |
sk.connect_ex(address) | 同上,只不過會(huì)有返回值,連接成功時(shí)返回 0 ,連接失敗時(shí)候返回編碼,例如:10061 |
sk.close() | 關(guān)閉套接字連接 |
sk.recv(bufsize[,flag]) | 接受套接字的數(shù)據(jù)。數(shù)據(jù)以字符串形式返回,bufsize指定最多可以接收的數(shù)量。flag提供有關(guān)消息的其他信息,通常可以忽略。 |
sk.recvfrom(bufsize[.flag]) | 與recv()類似,但返回值是(data,address)。其中data是包含接收數(shù)據(jù)的字符串,address是發(fā)送數(shù)據(jù)的套接字地址。 |
sk.send(string[,flag]) | 將string中的數(shù)據(jù)發(fā)送到連接的套接字。返回值是要發(fā)送的字節(jié)數(shù)量,該數(shù)量可能小于string的字節(jié)大小。即:可能未將指定內(nèi)容全部發(fā)送。 |
sk.sendall(string[,flag]) | 將string中的數(shù)據(jù)發(fā)送到連接的套接字,但在返回之前會(huì)嘗試發(fā)送所有數(shù)據(jù)。成功返回None,失敗則拋出異常。內(nèi)部通過遞歸調(diào)用send,將所有內(nèi)容發(fā)送出去。 |
sk.sendto(string[,flag],address) | 將數(shù)據(jù)發(fā)送到套接字,address是形式為(ipaddr,port)的元組,指定遠(yuǎn)程地址。返回值是發(fā)送的字節(jié)數(shù)。該函數(shù)主要用于UDP協(xié)議。 |
sk.settimeout(timeout) | 設(shè)置套接字操作的超時(shí)期,timeout是一個(gè)浮點(diǎn)數(shù),單位是秒。值為None表示沒有超時(shí)期。 |
sk.getpeername() | 返回連接套接字的遠(yuǎn)程地址。返回值通常是元組(ipaddr,port)。 |
sk.getsockname() | 返回套接字自己的地址。通常是一個(gè)元組(ipaddr,port) |
sk.fileno() | 套接字的文件描述符 |
TCP服務(wù)端
創(chuàng)建套接字,綁定套接字到本地IP與端口
開始監(jiān)聽連接
進(jìn)入循環(huán),不斷接受客戶端的連接請(qǐng)求
然后接收傳來的數(shù)據(jù),并發(fā)送給對(duì)方數(shù)據(jù)
傳輸完畢后,關(guān)閉套接字
TCP客戶端
創(chuàng)建套接字,連接遠(yuǎn)端地址
連接后發(fā)送數(shù)據(jù)和接收數(shù)據(jù)
傳輸完畢后,關(guān)閉套接字
s1.py為服務(wù)端
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
# 創(chuàng)建一個(gè)socket對(duì)象
sk = socket.socket()
# 綁定允許連接的IP地址和端口
sk.bind(('127.0.0.1', 6254, ))
# 服務(wù)端允許起來之后,限制客戶端連接的數(shù)量,如果超過五個(gè)連接,第六個(gè)連接來的時(shí)候直接斷開第六個(gè)。
sk.listen(5)
print("正在等待客戶端連接....")
# 會(huì)一直阻塞,等待接收客戶端的請(qǐng)求,如果有客戶端連接會(huì)獲取兩個(gè)值,conn=創(chuàng)建的連接,address=客戶端的IP和端口
conn, address = sk.accept()
# 輸入客戶端的連接和客戶端的地址信息
print(address, conn)
c1.py為客戶端
#!/usr/bin/env python
# _*_ coding:utf-8 _*_
import socket
# 創(chuàng)建一個(gè)socket對(duì)象
obj = socket.socket()
# 制定服務(wù)端的IP地址和端口
obj.connect(('127.0.0.1', 6254, ))
# 連接完成之后關(guān)閉鏈接
obj.close()
輸出的結(jié)果:
本文出自 “一盞燭光” 博客,謝絕轉(zhuǎn)載!
更多建議: