zoukankan      html  css  js  c++  java
  • 34.TCP非阻塞连接及套接字异常处理丶端口扫描脚本

    TCP非阻塞及套接字异常处理:


     TCP阻塞套接字异常捕获:

    • 套接字创建失败,8000
    1.  socket.error
    •  客户端连接错误:
    1.  ConnectionRefusedError
    2. socket.gaierror
    •  c.settimeout(1):
    1. 设置客户端超时
    2. 如果超时,引发:socket.timeout 
    3. 如果不设置该属性,引发的异常是:TimeoutError
    •  客户端套接字连接:
    1.  TCP:连接成功
    2. 连接之后:不可以,无法重复
    3. 连接不成功的话,也无法继续使用,因为套接字中的数据包和连接IP端口已经构建好了

    1,tcp_server.py

    import socket
    try:
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#ipv4,tsp协议
        ip = ''
        port = 22
        s.bind( (ip,port))   #只有服务端才会bind
        s.listen(5) #不是最大连接数,是最大连接等待数
    except socket.error:
        print('[E] Create socket failed')
    while True:
        try:
            c,c_addr = s.accept() #阻塞
            while True:
                date = c.recv(1024) #接受
                #date二进制
                if date:
                    c.send(date.decode().upper().encode()) #发送全大写的
                else:
                    c.close()   #关闭套接字
                    break
        except KeyboardInterrupt:
            c.close()
            break
    s.close()
    

    2.tcp_client.py 

    import socket
    import sys
    try:
        s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
        ip = '192.168.137.128'
        port = 22
    #    s.settimeout(2)  #设置客户端连接超时时间
        s.connect( (ip,port) )
    except socket.error:
        print('[E] Create Socket Failed')
        s.close()
    except socket.gaierror:
        print('[E] Failed To Connect Server')
        s.close()
    except ConnectionRefusedError:
        print('[E] Server Refuse')
        s.close()
    except socket.timeout:   #有效连接超时错误
        print('[E] Connect Timeout')
        s.close()
    '''
    except TimeoutError:
        print('[E] 连接超时')
    '''
    else:
        while True:
            try:
                msg = input('>>> ')
                s.send(msg.encode('utf-8'))
                date = s.recv(1024)
                if date:
                    print('[服务器]:',date.decode('utf-8'))
                else:
                    s.close()
                    break
            except KeyboardInterrupt:
                s.close()
                break

    TCP端口扫描.py

    #ssh TCP 22
    import socket
    import sys
    ip = input('IP:>>> ')
    open_port = []  #存储扫描成功链接的端口
    try:
        for port in range(1,65535):   #一般端口的取值范围
            try:
                s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
                s.settimeout(0.5)  #设置客户端连接超时时间 超过0.5s 则失败
            except socket.error:
                sys.exit('套接字创建失败')
            else:
                try:
                    s.connect ( (ip,port) )
                except socket.timeout:  # 如果出现端口不通,那么代表端口关闭
                    print('[closed]:%s' % port)
                else:
                    s.close()
                    open_port.append(port)
                del s  #套接字连接成功或者不成功,都无法继续使用,因为套接字中的数据包和连接IP端口已经构建好了,必须删除套接字才能继续循环下一个端口
        else:
            print('Open:%s' % open_port)
    except KeyboardInterrupt:
        print('终止...')
        sys.exit()
    

    运行结果: 

    IP:>>> 192.168.137.130
    [closed]:1
    [closed]:2
    [closed]:3
    [closed]:4
    [closed]:5
    终止... 

    TCP非阻塞:(企业用的最多,tcp服务器同时允许多个客户端连接)

    • 默认是阻塞的:
    1. 有人来吗?没人来连接会死等
    2. 专心致志服务你,其他人管不了了,1对1的专心服务
    • TCP非阻塞
    1. s.setblocking(0)    #0是费阻塞,1是阻塞
    2. BlockingIOError: [WinError 10035] 无法立即完成一个非阻止性套接字操作。这是一个不可避免的报错 ,所有我们要自定义异常报错
    • fzs_tcp_server.py
      import socket
      import copy
      try:
          s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)#ipv4,tsp协议
          s.bind( ('',8022))   #只有服务端才会bind
          s.listen(5) #不是最大连接数,是最大连接等待数
          s.setblocking(0) #1是阻塞 0是非阻塞
          connect_client = {} #创建一个dict
          connect_client_bak = {}
      except socket.error:
          print('[E] Create socket failed')
      while True:
          try:
              try:
                  c,c_addr = s.accept() #阻塞
                  #非阻塞,没有人来,我也会向下运行
              except BlockingIOError:         #没有人来连接 会报错
                  #print('暂时没有人来连接...')
                  pass
              else:
                  c.setblocking(0)
                  connect_client[c] = c_addr # 这个dict就是我的所有连接客户
                  #key:是套接字
                  #value: 地址 
                  connect_client_bak = copy.copy(connect_client) #拷贝
              for client in connect_client_bak:
                  if not client in connect_client: #客户端是真正连接的有效存在的
                      continue 
                  try:
                      date = client.recv(1024)
                  except BlockingIOError:
                      #print('[%s:%s]:没说话...' %  connect_client[client]) #打印出这个没说话的地址,connect_client[client]根据字典取出的值返回的是元组数据,列如:('192.168.137.130',8080)
                      pass
                  else:
                      if date:
                          print('[%s]:%s' % (connect_client[client],date.decode('utf-8')) )
                          while True:
                              msg = input('>>> ')
                              if msg:
                                  client.send(msg.encode('utf-8'))
                                  break
                              else:
                                  print('回复消息不能为空,请重新回复')
                      else:
                          print('[%s:%s]这人走了' % connect_client[client])
                          del connect_client[client]
                      del date
          except KeyboardInterrupt:
              break
      s.close()
      
    • fzs_tcp_client.py

      import socket
      import sys
      try:
          s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
          ip = '192.168.137.128'
          port = 8022
      #    s.settimeout(2)  #设置客户端连接超时时间
          s.connect( (ip,port) )
      except socket.error:
          print('[E] Create Socket Failed')
          s.close()
      except socket.gaierror:
          print('[E] Failed To Connect Server')
          s.close()
      except ConnectionRefusedError:
          print('[E] Server Refuse')
          s.close()
      except socket.timeout:   #有效连接超时错误
          print('[E] Connect Timeout')
          s.close()
      except socket.timeout:
          print('[E] Timeout')
          s.close()
      else:
          while True:
              try:
                  msg = input('>>> ')
                  s.send(msg.encode('utf-8'))
                  date = s.recv(1024)
                  if date:
                      print('[服务器]:',date.decode('utf-8'))
                  else:
                      s.close()
                      break
              except KeyboardInterrupt:
                  s.close()
                  break
      
    • 运行结果

      ^C[root@localhost date]# python3 fzs_tcp_server.py 
      [('192.168.137.1', 49856)]:111
      >>> 1111
      [('192.168.137.130', 49291)]:222
      >>> 2222
      [('192.168.137.130', 49291)]:aaa
      >>> aaaa
      [('192.168.137.1', 49856)]:bbb
      >>> bbbb
      [('192.168.137.1', 49856)]:zzzzzzzzzzzzzzz
      >>> zzz
      [('192.168.137.130', 49291)]:ccccccccccccccccccccccc
      >>> ccc
      

        

  • 相关阅读:
    分层图(了解一下,下一道比较好做)
    图论---The Captain
    数论
    NOIp复习计划
    20201116 Day4 卢卡斯定理
    20201113 Day3 斜率优化
    20201110Day2 分块
    20201030 day50 复习13:逆元、裴蜀定理
    20201030day50 模板全掌握
    20201029 day49 模拟(十八)
  • 原文地址:https://www.cnblogs.com/zhangan/p/10157196.html
Copyright © 2011-2022 走看看