Python Socket 編程

Socket建立函數

  • socket.socket(socket_family, socket_type, protocol=0)建立一個socket對象。socket_family是選擇地址族(因此都是AF_開頭),是不一樣的域(domain)。域決定者通訊的特徵,包括地址格式。參數socket_type是肯定套接字的類型,進一步肯定通訊特徵。protocol一般是0,表示爲給定的域和套接字類型選擇默認協議。當對同一域和套接字類型支持多個協議時,可使用protocol選擇一個特定的協議。在AF_INET通訊域中,套接字類型SOCK_STREAM的默認協議時傳輸控制協議(Transmission Control Protocol, TCP)。在AF_INET通訊域中,套接字類型SOCK_DGRAM的默認協議是UDP.
socket_family(address family,地址族) 意義
socket.AF_UNIX UNIX域(只可以用於單一的Unix系統進程間通訊),地址由單獨一個string表示
socket.AF_INET IPv4因特網域 (服務器之間網絡通訊),地址由(host, port)表示
socket.AF_INET6 IPv6因特網域,地址由(host, port, flowinfo, scopeid)表示
socket.AF_UNSPEC 未指定協議
socket_type 意義
socket.SOCK_STREAM 有序的,可靠的,雙向的,面向鏈接的字節流(默認TCP協議)
socket.SOCK_DGRAM 固定長度的,無鏈接的,不可開的報文傳遞
socket.SOCK_RAW IP協議的數據報接口
socket.SOCK_SEQPACKET 固定長度的,有序的,可靠的,面向鏈接的報文傳遞
protocol 意義
IPPROTO_IP IPv4協議
IPPROTO_IPV6 IPv6協議
IPPROTO_ICMP 因特網控制報文協議(Internet Control Message Protocol)
IPPROTO_RAW 原始IP數據包協議
IPPROTO_TCP 傳輸控制協議
IPPROTO_UDP 用戶數據報協議
  • 對於SOCK_DGRAM(數據報)接口,兩個對等進程之間同你不須要邏輯鏈接。只須要向對等進程所使用的套接字送出一個報文。所以SOCK_DGRAM提供了一個無鏈接的服務。
  • 對於SOCK_STREAM(字節流)接口,要求在交換數據以前,在本地套接字和通訊的對等進程的套接字之間創建一個邏輯鏈接。因爲SOCK_TREAM套接字提供字節流服務,因此應用程序分辨不出報文的界限。這意味者從SOCK_STREAM套接字讀取數據時,它也許不會返回全部由發送進程所寫的字節數。最終能夠得到發送過來的全部數據,但也須要經過若干次函數調用才能獲得。
  • SOCK_SEQPACKET套接字和SOCK_STREAM套接字很相似,只是從套接字獲得的是基於報文的服務而不是字節流的服務。這意味着從SOCK_SEQPACKET套接字接受的數據量與對方發送的一致。流控制傳輸協議(Stream Control Transmission Protocol, SCTP)提供了因特網上的順序數據包服務。
  • SOCK_RAW套接字提供一個數據報接口,用於直接訪問下面的網絡層(IP層)。使用這個接口的時候,應用程序負責構造本身的協議頭部。PS:須要有超級管理員權限,防止惡意應用程序繞過內建安全機制來建立報文。

其餘建立socket函數

  • socket.socketpair([family[, type[, proto]]])建立一對已經鏈接的socket對象(返回(socket, socket)),familytypeproto和上述socket()同樣。部分平臺默認的family是AF_UNIX,不然,默認是AF_INET。例如:AF_UNIX
  • socket.fromfd(fd, family, type[, proto])複製文件描述符fd(文件描述符fd是一個整數且有一個文件對象的fileno()方法返回)且用此返回一個socket對象。familytypeproto和上述socket()同樣。文件描述符fd應該是制定一個socket的,但函數並無檢測,若是這個文件描述符fd是無效的,隨後的操做將會失敗。這個方法不多會用到,可是可以用來在一個被看成標準輸入輸出的程序的socket中設置或獲取配置(如:一個由Unix inet daemon啓動的服務)。socket被假設爲阻塞模式。(在Unix上有效)

其餘函數

  • socket.getdefaulttimeout()返回下一個新的socket對象的超時時間,單位是秒(float)。若是返回是None表示新的socket對象沒有超時。第一次導入socket包時,默認是None
  • socket.setdefaulttimeout(timeout)設置默認超時時間給新的socket對象,單位是秒(float)。None表示新的socket對象沒有超時。第一次導入socket包時,默認是None

地址

字節序

字節序是一個處理器架構特性,用於指示像整數這樣的大數據類型內部的字節如何排序。html

大端(bing-endian)字節序,最大字節地址出如今最低有效字節(Least Significant Byte, LSB)上。python

小端(little-endian)字節序,最低有效字節包含最小字節地址。安全

無論字節如何排序,最高有效字節(Most Signification Byte, MSB)老是在左邊,LSB老是在右邊。 大端 小端服務器

對於TCP/IP協議棧使用大端字節序。網絡

有下面四個函數來轉換字節序:架構

  • socket.ntohl(x):將32位正整數從網絡字節序轉換到主機字節序。在一些機器上的主機字節序和網絡字節序是同樣的,這將是一個空操做;不然,它執行一個4字節交換操做。
  • socket.ntohs(x):將16位正整數從網絡字節序轉換到主機字節序。在一些機器上的主機字節序和網絡字節序是同樣的,這將是一個空操做;不然,它執行一個2字節交換操做。
  • socket.htonl(x):將32位正整數從主機字節序轉換到網絡字節序。在一些機器上的主機字節序和網絡字節序是同樣的,這將是一個空操做;不然,它執行一個4字節交換操做。
  • socket.htons(x):將16位正整數從主機字節序轉換到網絡字節序。在一些機器上的主機字節序和網絡字節序是同樣的,這將是一個空操做;不然,它執行一個2字節交換操做。

地址格式

  • socket.inet_aton(ip_string)將一個字符串的IPv4地址(e.g:「192.168.1.1」)轉換爲32位二進制格式的字符串(在和一些採用C標準庫和須要struct in_addr的程序交流上頗有用)。若是ip_string是一個無效的ip,這將引發一個socket.error
  • socket.inet_ntoa(packed_ip)將一個32位二進制格式的字符串IPv4地址轉換成一個經常使用的IPv4字符串。若是這不是一個表示4byte長度的字符串,將引發一個socket.error
  • socket.inet_pton(address_family, ip_string)將一個對應family(AF_INET 或 AF_INET6)的字符串地址,轉換成對應的二進制格式。(在*nix上)
  • socket.inet_ntop(address_family, packed_ip)將一個二進制格式的IP地址,轉換成對應地址族的字符串格式。(AF_INET 或 AF_INET6)

地址查詢

  • socket.getaddrinfo(host, port[, family[, socktype[, proto[, flags]]]])根據給定的參數host/port,相應的轉換成一個包含用於建立socket對象的五元組的list。dom

    • host能夠是一個域名(e.g:"www.google.com"),能夠是一個IPv4或者IPv6地址的字符串,或則是None
    • port能夠是一個協議名(e.g:"http"),能夠是一個表明端口的數字,或者是None
    • familysocketypeprotoflags都是一些可選的參數,來篩選結果的。默認狀況下,它們的值都是 0,表示全部。 flags能夠是 1 個或者多個AI_*常量,這會影響結果是如何計算和返回的。默認值是 0

    返回list的5元組結構:(family, socktype, proto, canonname, sockaddr), familysocktpyeproto是一個整數。canonname是一個string,僅當AI_CANONNAME在參數flags中,不然返回 '' 。若是familyAF_INETsockaddr(address, port);若是familyAF_INET6sockaddr(address, port, flow, info, scope id)異步

    flag標記 描述
    AI_ADDRCONFIG 查詢配置的地址類型(IPv4或IPv6)
    AI_ALL 查找 IPv4 和 IPv6 地址(僅用於AI_V4MAPPED)
    AI_CANONAME 須要一個規範的名字(與別名相對)
    AI_NUMBERICHOST 以數字格式指定主機地址,不翻譯
    AI_NUMBERICSERV 將服務指定爲數字端口號,不翻譯
    AI_PASSIVE 套接字地址用於監聽綁定
    AI_V4MAPPED 若是沒有找到IPv6地址,返回映射到IPv6格式的IPv4地址
  • socket.gethostname()返回當前正在執行Python解釋器的主機名的字符串。(gethostname()返回的可能不是一個徹底的qualified主機名,詳見getfqdn()socket

  • socket.getfqdn([name])使用name來返回一個full qualified的主機名。若是name沒有提供或者爲空,則被解釋爲本地主機。爲了找返回一個full qualified的主機名,由gethostbyaddr()返回的主機名將被選中,若是有的主機有別名的話,將會跟在後面。第一個返回的主機名是被選中的。若是沒有full qualified主機名可用,將返回gethostbyaddr()的主機名。tcp

  • socket.gethostbyname(hostname)將一個hostname轉換爲IPv4地址格式。若是hostname是一個IPv4地址,將會原封不動返回。gethostbyname()不接受IPv6。

  • socket.gethostbyname_ex(hostname)擴展接口。將一個hostname轉換爲IPv4地址格式。返回一個三元組(hostname, aliaslist, ipaddrlist)hostname是反映着返回的ip_addressaliaslist是一組對應着同一個IP地址的主機別名(可能爲空)。ipaddrlist是一組對應着同一個hostname的IPv4地址(通常狀況是單一個地址)。gethostbyname_ex()只支持IPv4。

  • socket.gethostbyaddr(ip_address)``````hostname是反映着返回的ip_addressaliaslist是一組對應着同一個IP地址的主機別名(可能爲空)。ipaddrlist是一組同一主機同一接口的IPv4/IPv6的地址列表。

  • socket.getnameinfo(sockaddr, flags)將給定的socketaddr(爲一個host和port的二元組)翻譯成一個二元組(host, port)。根據設置和flags,結果能夠保存一個full qualified的主機名或者表如今主機上的數字地址。一樣的,端口號能夠爲數字或者字符串。

flags 描述
NI_DGRAM 服務基於數據報而非基於流
NI_NAMEREQD 若是找不到主機名,將其做爲一個錯誤對待
NI_NOFQDN 對於本地主機,僅返回全限定域名的字節點部分
NI_NUMERICHOST 返回主機地址的數字形式,而非主機名
NI_NUMERICSCOPE 對於IPv6,返回範圍ID的數字形式,而非名字
NI_NUMERICSERV 返回服務地址的數字形式(即端口號),而非名字
  • socket.getprotobyname(protocolname)將一個網絡協議名(例如「icmp」,"tcp")轉換成爲一個固定的合適的值,給socket()的第三個參數(可選)。這個一般用在SOCK_RAW模式,對於其餘普通的socket模型,將這個參數缺省或者設爲0會自動的選擇正確的協議。
  • socket.getservbyname(servicename[, protocolname])將一個網絡服務名(e.g: "http")和協議名轉換成一個該服務的端口號。protocolname是可選項,應該是tcp或者udp,不然將匹配任何協議。
  • socket.getservbyport(port[, protocolname])將一個端口號和網絡協議名轉換成該端口號的服務名。protocolname是可選項,應該是tcp或者udp,不然將匹配任何協議。

Socket對象方法

  • socket.accept()接受一個鏈接。這個socket對象必須綁定了一個地址並正在監聽着鏈接。返回的值是(conn, address)conn是一個用來在接連上發送接收數據的新的socket對象,address是綁定在另一個的socket鏈接的地址。

  • socket.bind(address)將socket綁定到一個address。這個socket必須是未綁定地址的(address的格式如上文提到的,e.g:IPv4的格式(host, port))。

  • socket.close()關閉這個socket。接下來在這個socket對象的操做都將失敗。另一端將不在接收到數據(當隊列中的數據都發送後)。當socket對象被垃圾回收機制回收時,將會自動關閉。

  • socket.connect(address)address鏈接到一個遠程的socket(address的格式如上文提到的,e.g:IPv4的格式(host, port)

  • socket.connect_ex(address)相似於socket.connect(address),可是返回一個錯誤提示來取代引發一個C語言層connect()的錯誤exception(其餘問題,若是「host not found」,依然會引發exception)。若是返回的錯誤提示時0則操做成功,其餘則是errno變量。這是一個有用的支持,好比,異步鏈接。

  • socket.fileno()返回一個socket對象的文件描述符(一個整數)。在作多路複用socket(select,poll,epoll)下有用。在Window下,這個方法返回的整數不能當作文件描述符來使用(好比os.fdopen())。Unix下沒有這個限制。

  • socket.getpeername()返回socket鏈接的遠程address。這是有用的,例如找出遠程的IPv4/v6 socket的端口號(返回的address格式依賴於地址族-如上述)。這個方法在某些平臺上不支持。

  • socket.getsockname()返回socket綁定的address。這是有用的,例如找IPv4/v6 socket的端口號(返回的address格式依賴於地址族-如上述)。

  • socket.getsockopt(level, optname[, buflen])返回指定socket選項的值。optname所須要的 symbolic 常量(so_*)都在本module中。若是buflen缺省,將會假定是一個整數的設置,而且這個函數是返回一個整數的。若是buflen設置了,它指定用於接收緩衝的最大長度。須要由調用者來對這個緩衝的內容進行解碼。

  • socket.setsockopt(level, optname, value)設置給定socket選項的值。optname所須要的 symbolic 常量(so_*)都在本module中。value能夠是一個整數(integer)或者表示緩衝(buffer)的字符串(string)。在後一種狀況(指字符串的狀況),它是由調用者來保證字符串包含着正確的位(bits)。

    參數level標識了選項應用的協議。若是是通用的套接字層次選項,則level設置成SOL_SOCKET,不然level設置成控制這個選項的協議編號。對於TCP選項,levelIPPROTO_TCP。對於IP,levelIPPROTO_IP等等。

選項 參數value的類型 描述
SO_ACCEPTCONN integer 返回信息指示該套接字是否能被監聽(僅getsockopt()
SO_BROADCAST integer 若是value非0,廣播數據包
SO_DEBUG integer 若是value非0,啓動網絡驅動調試功能
SO_DONTROUTE integer 若是返回的value非0,繞過一般路由
SO_ERROR integer 返回掛起的套接字錯誤並清除(僅getsockopt)
SO_KEEPALIVE integer 若是value非0,啓動週期性keep-alive報文
SO_LINGER stirng 當還有未發送報文二套接字已關閉時,延遲時間
SO_OOBINLINE integer 當value非0,將帶外數據放在普通數據中
SO_RCVBUF integer 接受緩衝區的字節長度
SO_RCVLOWAT integer 接收調用中返回的最小數據字節數
SO_RCVTIMEO string 套接字接收調用的超時值
SO_REUSEADDR integer 若是value非0,重用bind中的地址
SO_SNDBUF integer 發送緩衝區的字節長度
SO_SNDLOWAT integer 發送調用中傳送的最小數據字節數
SO_SNDTIMEO string 套接字發送調用的超時值
SO_TYPE integer 表示套接字類型(僅getsockopt
  • socket.listen(backlog)監聽Socket進行的鏈接。backlog指定鏈接隊列的最大值,至少爲0。最大值取決於系統(一般爲5)。最小值被強制爲0。

  • socket.makefile([mode[, bufsize]])返回與socket相關聯的文件對象。這個文件對象只有調用close()方法纔會被關閉,但這個關閉只是刪除與socket的關聯,因此只有在這個socket沒有在其餘地方被引用時,socket纔會關閉。 這個socket必須在阻塞模式(不能有超時)。可選參數modebufsize和大開文件的方法file()open同樣。

  • socket.recv(bufsize[, flags])接收來自socket的數據。接收的數據以string類型表示。一次接收數據的最大數量由bufsize決定。flags的默認值爲0,flags的標誌以下表。

標誌 描述(Linux下)
MSG_CMSG_CLOEXEC 爲UNIX域套接字上接收的文件描述符設置執行時關閉標誌
MSG_DONTWAIT 啓動非阻塞操做(至關於使用O_NONBLOCK)
MSG_ERRQUEUE 接受錯誤信息做爲輔助數據
MSG_OOB 若是協議支持,獲取帶外數據
MSG_PEEK 返回數據內容而不是真正取走數據
MSG_TRUNC 即便數據包被截斷,也返回數據包的實際長度
MSG_WAITALL 等待直到全部數據可能(僅SOCK_STREAM)
  • socket.recvfrom(bufsize[, flags])接收來自socket的數據。返回的值時一個二元組(string, address)string表示的是接收的數據,address則是發送數據的socket的地址。參數的詳解參見socket.recv(bufsize[, flags])
  • socket.recvfrom_into(buffer[, nbytes[, flags]])接收來自socket的數據,將接收的數據寫入到buffer中,而不是返回一個string。返回值的一個二元組(nbytes, address),nbytes是接收的的字節數,address則是發送數據的socket的地址。flags參數的詳解參見socket.recv(bufsize[, flags])
  • socket.send(string[, flags])發送數據到socket。這個socket對象必須已經與一個遠程的socket對象鏈接。可選參數flags和函數recv()中的同樣。這個函數會返回發送數據的字節數。應用程序須要本身負責檢查是否全部數據已經被髮送,若是隻有一部分數據發送了,應用程序須要嘗試將剩餘的數據輸送出去。
  • socket.sendall(string[, flags])發送數據到socket。這個socket對象必須已經與一個遠程的socket對象鏈接。可選參數flags和函數recv()中的同樣。和send()不一樣的是,這個方法將會一直髮送數據直到全部數據都發送完或者有錯誤出現。若是成功則返回None。若是錯誤,將會引發一個異常(exception),但這樣將沒有辦法獲知有多少數據是成功被髮送的。
  • socket.sendto(string, address)socket.sendto(string, flags, address)發送數據到socket,這個socket必須是沒有與遠程的socket鏈接的,目標socket由address來決定。可選參數falgsrecv()相同。函數返回的結果是發送數據的字節數。(address的格式由地址族決定,看上文)
  • socket.setblocking(flag)將這個socket設置爲阻塞非阻塞:若是flag設爲0,那個它是非阻塞,其餘則爲阻塞。全部的socket默認是阻塞的。在非阻塞模式下,若是調用recv()沒有接收到數據,或者send()不能馬上的發送數據,一個error一個將會引發。在阻塞模式下,這些方法將會阻塞知道它們可以處理。socket.setblocking(0)的效果和socket.setblocking(0.0)同樣。socket.setblocking(1)的效果和socket.setblocking(None)同樣。
  • socket.settimeout(value)爲阻塞的socket設置一個超時時間。value能夠是一個非負float表示的數字,單位是秒,也能夠是None。若是給socket設定一個超時時間(float),一連串的阻塞方法的處理時間超過這個值,將會引發一個timeout異常。若是valueNone,則會禁用超時。settimeout(0.0)效果和setblocking(0)同樣。settimeout(None)的效果和setblocking(1)同樣。
  • socket.gettimeout()返回設置的超時時間。返回的值和setblocking()settimeout()相關。
  • socket.setsockopt(level, optname, value)用給定的參數設置socket的配置。所需的配置常量在socketmodule中(SO_*etc.)。value能夠是一個整數或者一個字符串表示的buffer。若是是一個buffer,將有調用着來驗證字符串是否包含正確的位(bits)。
  • socket.shutdown(how)徹底關閉鏈接或者關閉一半。若是howSHUT_RD,將不能接收數據。若是howSHUT_WR,將不能發送數據。若是是SHUT_RDWD,發送和接收都不容許。
相關文章
相關標籤/搜索