Python-socket總結

socket是什麼

什麼是socket所謂socket通常也稱作"套接字",用於描述IP地址和端口,是一個通信鏈的句柄。

應用程序通常通過"套接字"向網絡發出請求或者應答網絡請求。說白了就是一種通信機制。

列入你和移動客服諮詢問題時,會有一個客服爲你解決問題一樣,就是你和客服間的相互通信

在socket裏就是“發送”和“接收”這兩個動作就是socket通信方式

socket.gethostname()     # 獲取主機名

from socket import *     # 避免 socket.socket()

s=socket()

s.bind()         # 綁定地址到套接字

s.listen()       # 開始TCP監聽

s.accept()       # 被動接受TCP客戶端連接,等待連接的到來

s.connect()      # 主動初始化TCP服務器連接

s.connect_ex()   # connect()函數的擴展版本,出錯時返回出錯碼,而不是跑出異常

s.recv()         # 接收TCP數據

s.send()         # 發送TCP數據

s.sendall()      # 完整發送TCP數據

s.recvfrom()     # 接收UDP數據

s.sendto()       # 發送UDP數據

s.getpeername()  # 連接到當前套接字的遠端的地址(TCP連接)

s.getsockname()  # 當前套接字的地址

s.getsockopt() # 返回指定套接字的參數

s.setsockopt()   # 設置指定套接字的參數

s.close()        # 關閉套接字

s.setblocking()  # 設置套接字的阻塞與非阻塞模式

s.settimeout()   # 設置阻塞套接字操作的超時時間

s.gettimeout()   # 得到阻塞套接字操作的超時時間

s.filen0()       # 套接字的文件描述符

s.makefile()     # 創建一個與該套接字關聯的文件對象

socket.AF_UNIX # 只能夠用於單一的Unix系統進程間通信

socket.AF_INET # 服務器之間網絡通信

socket.AF_INET6 # IPv6

socket.SOCK_STREAM  # 流式socket , for TCP

socket.SOCK_DGRAM  # 數據報式socket , for UDP

socket.SOCK_RAW      # 原始套接字,普通的套接字無法處理ICMP、IGMP等網絡報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文;此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭。

socket.SOCK_RDM  # 是一種可靠的UDP形式,即保證交付數據報但不保證順序。SOCK_RAM用來提供對原始協議的低級訪問,在需要執行某些特殊操作時使用,如發送ICMP報文。SOCK_RAM通常僅限於高級用戶或管理員運行的程序使用。

socket.SOCK_SEQPACKET # 可靠的連續數據包服務

基礎講解

    # 創建socket對象

    sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    # 監聽端口

    sock.bind(('127.0.0.1',8001))

    # 開始監聽,

    sock.listen(5)


    while True:

        # 阻塞,deng 。。。。

        # 直到有請求連接

        print '....'

        connection, address = sock.accept()

        # connection,代表客戶端socket對象,

        # address,客戶端IP地址

        #handle_request(connection)

        buf = connection.recv(1024)

        print buf

        connection.send("HTTP/1.1 200 OK\r\n\r\n")

        connection.send("Hello, World")

        connection.close()

#服務端

import socket 

HOST=''  #空代表0.0.0.0

PORT= 6666  #監聽端口

s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) 

s.bind((HOST,PORT)) 

s.listen(1) 

while True:

    conn,addr= s.accept()   

    print'Connected by', addr 

    while  True:

        data = conn.recv(1024) #接收1024字節數據

        if not data: break     #如果收不到客戶端數據了(代表客戶端斷開了),就斷開

        conn.sendall(data.upper())    #將收到的數據全變成大寫再發給客戶端 

    conn.close() #關閉此客戶端的連接實例

#客戶端

import socket 

HOST='' 

PORT= 6666  #監聽端口

s= socket.socket(socket.AF_INET,socket.SOCK_STREAM) 

s.bind((HOST,PORT)) 

s.listen(1) 

while True:

    conn,addr= s.accept()   

    print'Connected by', addr 

    while  True:

        data = conn.recv(1024) #接收1024字節數據

        if not data: break     #如果收不到客戶端數據了(代表客戶端斷開了),就斷開

        conn.sendall(data.upper())    #將收到的數據全變成大寫再發給客戶端 

    conn.close() #關閉此客戶端的連接實例

    服務端socket在使用bind方法之後調用listen方法去監聽一個給定的 地址。然後,客戶端socket就可以通過使 用 connect方法(connect方法所使用的地址參數與bind相同)去連接服務端。listen方法 要求一個參數,這個參數就是等待連接隊列中所能包含的連接數。

    一旦服務端socket調用了listen方法,就進入了臨聽狀態,然後通 常使用一個無限的循環:1、開始接受客房端的連接,這通過調用accept方法來實現。調用了這個方法後將處於阻塞狀態(等待客戶端發起連接)直到一個客 戶端連接,連接後,accept返回形如(client,address)的一個元組,其中client是一個用於與客戶端通信的 socket,address是客戶端的形如xxx.xxx.xxx.xxx:xxx的地址;2、然後服務端處理客戶端的請求;3、處理完成之後又調用 1。



#以上例子是單線程的只能一對一的服務,即服務端只能處理一個鏈接,想要處理多線程怎麼辦,不用急多線程的Python已給我們寫好直接調用就好


socket服務端

#用於處理多線程的模塊

    import SocketServer

    import os

    class MyTCP(SocketServer.BaseRequestHandler):

        def handle(self):

            while True:

                self.data=self.request.recv(1024).strip() #接受數據

                if self.data == 'quit' or not self.data:break #如果沒有數據或爲quit 退出

                cmd_data=os.popen(self.data).read() #將命令結果存爲字符串

                if cmd_data == '':cmd_data= self.data + ': Command not found' #如果命令結果爲空或命令返回爲空

                self.request.sendall(cmd_data) #發送所有的數據

    if __name__ == '__main__':

        HOST,PORT = '127.0.0.1',6666 #綁定端口和ip

        server = SocketServer.ThreadingTCPServer((HOST,PORT),MyTCP) #將寫的類加入多線程處理

        server.serve_forever() #循環啓動

socket客戶端

    import socket

    HOST='127.0.0.1'

    PORT=6666

    s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #服務期間的TCP通信

    s.connect((HOST,PORT)) #綁定端口和ip

    while True:

        while True: #如果命令爲空繼續輸入

            cmd=raw_input('CMD:').strip()

            if cmd != '':break

        s.sendall(cmd) #發送所有數據

        data=s.recv(1024).split('\n') #以換行符分割接收的數據

        print 'cmd:'

        for line in data:print line #循環打印數據

    s.close() #關閉套接字


用SocketServer創建一個服務器需要三步:

1、通過子類化BaseRequestHandler類和覆蓋它的handle()方法來創建一個請求處理器類,用於處理進來

的請求;
2、實例化服務類如TCPServer,並傳遞給它參數:服務器地址和請求處理器類;
3、調用服務實例對象的handle_request()或serve_forever()方法去處理請求。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章