在網絡應用中,經常會遇到這種情況:一方嘗試連接,但另一方由於網絡媒介失效或者其他原因無法響應。
Python的Socket庫提供了一個方法,能通過socket。error異常優雅地處理套接字錯誤。
1. 代碼及相關解釋
1 # ! /usr/bin/env python 2 # -*- coding: utf-8 -*- 3 # 處理套接字錯誤 4 5 import argparse 6 # python用於解析命令行參數和選項的標准模塊 7 import sys 8 import socket 9 10 # 定義main_errors()類 11 def main_errors(): 12 # 創建一個解析對象,其中描述為"Socket Error Examples" 13 # ArgumentParser(self, prog=None, usage=None, description=None, epilog=None, 14 # version=None, parents=[], formatter_class=HelpFormatter, prefix_chars='-', 15 # fromfile_prefix_chars=None, argument_default=None, conflict_handler='error', 16 # add_help=True) 17 18 # Keyword Arguments: 19 # - prog -- The name of the program (default: sys.argv[0]) 20 # - usage -- A usage message (default: auto-generated from arguments) 21 # - description -- A description of what the program does 22 # - epilog -- Text following the argument descriptions 23 # - parents -- Parsers whose arguments should be copied into this one 24 # - formatter_class -- HelpFormatter class for printing help messages 25 # - prefix_chars -- Characters that prefix optional arguments 26 # - fromfile_prefix_chars -- Characters that prefix files containing additional arguments 27 # - argument_default -- The default value for all arguments 28 # - conflict_handler -- String indicating how to handle conflicts 29 # - add_help -- Add a -h/-help option 30 parser = argparse.ArgumentParser(description='Socket Error Examples') 31 32 # 采用add_argument方法,add_argument(name or flags…[, action][, nargs][, const] 33 # [, default][, type][, choices][, required][, help][, metavar][, dest]) 34 # name or flags —— 必須的參數,該參數接收選項參數或者是位置參數 35 # action: 36 # (1)store —— 默認action模式,儲存值到指定變量 37 # (2)store_const —— 儲存值在參數的const部分指定,多用於實現非布爾的命令行flag 38 # (3)store_true/store_false —— 布爾開關。可以2個參數對應一個變量 39 # (4)append —— 儲存值到列表,儲存值在參數的const部分指定 40 # (5)append_const —— 儲存值到列表,儲存值在參數的const部分指定 41 # (6)version —— 輸出版本信息然后退出 42 # nargs —— 指定接受多個或者0個參數 43 # const —— 配合action="store_const|append_const"使用,默認值 44 # default —— 設置參數的默認值 45 # type —— 把從命名行輸入的結果轉成設置的類型,通常用來檢查值的范圍,以及合法性。默認string 46 # choices —— 檢查輸入參數的范圍 47 # required —— 指定某個選項在命名中出現, 默認False, 若為 True, 表示必須輸入該參數 48 # help —— 參數描述 49 # metavar —— 用於help信息輸出 50 # dest —— 把位置或者選項關聯到一個特定的名字 51 # http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=21633169&id=4387657 參數詳解 52 parser.add_argument('--host', action='store', dest='host', required=False) 53 parser.add_argument('--port', action='store', dest='port', required=False) 54 parser.add_argument('--file', action='store', dest='file', required=False) 55 56 # 調用parse_args()方法進行解析 57 # def parse_args(self, args=None, namespace=None): 58 # args, argv = self.parse_known_args(args, namespace) 59 # if argv: 60 # msg = _('unrecognized arguments: %s') 61 # self.error(msg % ' '.join(argv)) 62 # return args 63 given_args = parser.parse_args() 64 host = given_args.host 65 port = given_args.port 66 filename = given_args.file 67 # First try-except block -- create socket 68 # 處理創建套接字異常 69 try: 70 s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 71 except socket.error as e: 72 print("Error creating socket: %s" % e) 73 sys.exit(1) 74 # Second try-except block -- connect to giver host/port 75 # 處理連接套接字異常 76 try: 77 s.connect((host, port)) 78 except socket.gaierror as e: 79 print("Address-related error connecting to server: %s" % e) 80 sys.exit(1) 81 # Third try-except block -- sending data 82 # 處理發送數據錯誤 83 try: 84 # GET方法 發送到網站 85 data = "GET %s HTTP/1.0\r\n\r\n" % filename 86 s.sendall(data.encode()) 87 except socket.error as e: 88 print("Error sending data: %s" % e) 89 sys.exit(1) 90 while 1: 91 try: 92 # 接收網站返回的數據 93 buf = s.recv(2048) 94 except socket.error as e: 95 print("Error receiving data: %s" % e) 96 sys.exit() 97 if not len(buf): 98 break 99 # 將buf數據發送到命令行中 100 sys.stdout.write(str(buf)) 101 102 if __name__ == '__main__': 103 main_errors()