Python学习五(网络编程、socket()函数、端口扫描)

Python学习

网络编程

1. C/S架构

C: Client、S: Server,即客户机和服务器结构。Server唯一的目的就是等待Client的请求,Client连上Server发送必要的数据,然后等待Server端完成请求的反馈。

基本原理:Server端进行设置,首先创建一个通信端点,让Server端能够监听请求,之后就进入等待和处理Client请求的无限循环中。Client编程相对Server端编程简单,只要创建一个通信端点,建立到服务器的连接,就可以提出请求了。

2. Python提供的网络服务

Python 提供了两个级别访问的网络服务。

  1. 低级别的网络服务支持基本的 Socket,它提供了标准的 BSD Sockets API,可以访问底层操作系统Socket接口的全部方法。
  2. 高级别的网络服务模块 SocketServer, 它提供了服务器中心类,可以简化网络服务器的开发。
  3. 什么是 Socket?
    Socket又称"套接字",应用程序通常通过"套接字"向网络发出请求或者应答网络请求,使主机间或者一台计算机上的进程间可以通讯。

3. socket()函数

socket.socket(family, type)
  • family: 套接字家族可以是 AF_UNIX 或者 AF_INET;

AF_UNIX 和 AF_INET是两种不同的通信域,AF_UNIX域只能用于本机内进程通信、AF_INET不仅可以用作本机的跨进程通信,同样的可以用于不同机器之间的通信。

AF_INET需经过多个协议层的编解码,消耗系统cpu,并且数据传输需要经过网卡,受到网卡带宽的限制。AF_UNIX数据到达内核缓冲区后,由内核根据指定路径名找到接收方socket对应的内核缓冲区,直接将数据拷贝过去,不经过协议层编解码,节省系统cpu,并且不经过网卡,因此不受网卡带宽的限制。所以AF_UNIX的传输速率远远大于AF_INET。

  • type:套接字类型可以根据是面向连接的还是非连接分为:SOCK_STREAM或SOCK_DGRAM

如:创建TCP/IP套接字

s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  1. 服务端套接字的方法
s.bind()
# 绑定地址(host,port)到套接字,以元组(host,port)的形式表示地址。
s.listen()		
# 开始TCP监听,操作系统可以挂起的最大连接数量,该值至少为1,大部分应用程序设为5就可以了。
s.accept()	
# 被动接受TCP客户端连接,(阻塞式)等待连接的到来
  1. 客户端套接字方法
s.connect()	
# 主动初始化TCP服务器连接,一般address的格式为元组(hostname,port),如果连接出错,返回socket.error错误。
s.connect_ex()
# connect函数的扩展版本,出错时返回错误代码,而不抛出异常
s.recv()	
# 接收TCP数据,数据以字符串形式返回,要指定接收的最大数据量
  1. 公共用途套接字方法
s.recv()           接受TCP数据
s.send()           发送TCP数据
s.sendall()        完整发送TCP数据
s.recvfrom()       接受UDP数据
s.sendto()         发送UDP数据
s.getpeemame()     连接到当前套接字的远端地址
s.getsockname()    当前套接字的地址
s.getsockopt(      返回指定套接字的参数
s.setsockopt()     设置指定套接字的参数
s.close()          关闭套接字

4. 实例

4.1 实例一

基于C/S架构创建一个TCP服务端和客户端。

  • 服务端:
import socket

# 创建 socket 对象
serversocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 获取本地主机名
host = socket.gethostname()

port = 8888

# 绑定端口号
serversocket.bind((host, port))

# 设置最大连接数,超过后排队
serversocket.listen(5)

while True:
    # 建立客户端连接
    clientsocket,addr = serversocket.accept()

    print("连接地址: %s" % str(addr))

    msg='欢迎访问服务端!'+ "\r\n"
    clientsocket.send(msg.encode('utf-8'))
    clientsocket.close()
  • 客户端
import socket

# 创建 socket 对象
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 获取本地主机名
host = socket.gethostname()

# 设置端口号
port = 8888

# 连接服务,指定主机和端口
s.connect((host, port))

# 接收小于 1024 字节的数据
msg = s.recv(1024)

s.close()

print (msg.decode('utf-8'))

先运行服务端,然后运行客户端,结果:

在这里插入图片描述
在这里插入图片描述

4.1 实例二

基于C/S架构创建一个TCP服务端和客户端,并实现通信和cmd命令。

  • 服务端
import socket
import time
import os

COD = 'utf-8'
HOST = socket.gethostname()
PORT = 9999
BUFSIZ = 1024
SIZE = 5
ADDR = (HOST, PORT)

tcpServer = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 创建套接字
tcpServer.bind(ADDR)    # 绑定ip端口号
tcpServer.listen(SIZE)  # 设置最大链接数

while True:
    print("服务器启动,监听客户端连接...")
    tcpClient, addr = tcpServer.accept()
    print("连接的客户端为:", addr)

    while True:
        try:
            data = tcpClient.recv(BUFSIZ).decode(COD)
            x = time.strftime("%Y-%m-%d %X")
            msg = '[%s ==> Client]:%s' % (x, data)

            if data == 'cmd':
                print(msg)
                tcpClient.send('已进入命令行模式...'.encode(COD))
                while True:
                    data = tcpClient.recv(BUFSIZ).decode(COD)
                    tcpClient.send(os.popen(data).read().encode(COD))
            else:
                print(msg)
                data = input('Server~:')
                tcpClient.send(data.encode('utf-8'))

        except Exception:
            print("断开的客户端为:", addr)
            break

# 关闭连接
tcpClient.close()
tcpServer.close()
  • 客户端
import socket
import time

HOST = socket.gethostname()
PORT = 9999
BUFSIZ = 1024
COD = 'utf-8'
ADDR = (HOST, PORT)

tcpClient = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
tcpClient.connect(ADDR)

while True:
    msg = input('Client~:')
    x = time.strftime("%Y-%m-%d %X")
    tcpClient.send(msg.encode(COD))
    recv_data = tcpClient.recv(1024).decode(COD)
    result = '[%s ==> Server]:%s' % (x, recv_data)
    print(result)

# 关闭连接
tcpClient.close()

运行结果:

客户端

在这里插入图片描述

服务端

在这里插入图片描述

5. 端口扫描

原理:使用 s.connect(hostname,port) 方法进行TCP服务器连接,连接成功即该端口开放,反之关闭。

import socket

print('Please input ip:')
ip = input()
print('Please input ports(use , separated):')
ports = input().split(',')   # 用列表存储


def do_open(ip, ports):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((ip, ports))
        return True
    except:
        return False


def do_scanPort(ip, ports):
    print('Start port scan...')
    for i in ports:
        if do_open(ip, int(i)):
            print('%s ==> host %s is [open]' % (ip, i))
        else:
            print('%s ==> host %s is [close]' % (ip, i))


if __name__ == '__main__':
    do_scanPort(ip, ports)

扫描结果:

在这里插入图片描述

6. 网络编程的其他模块

协议     功能	         端口号	           Python模块

HTTP	网页访问	          80	   httplib, urllib, xmlrpclib
NNTP	阅读和张贴新闻文章	  119	           nntplib
FTP	    文件传输	          20         	ftplib, urllib
SMTP	发送邮件        	  25	           smtplib
POP3	接收邮件	          110	           poplib
IMAP4	获取邮件	          143	           imaplib
Telnet	命令行	          23	           telnetlib
Gopher	信息查找	          70	       gopherlib, urllib
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值