网络编程(三)

Python网络编程入门(二)

一.TCP流式套接字的应用

1.HTTP网页传输

1)HTTP协议:超文本传输协议,属于应用层协议,应用层协议可以选择传输层服务。
      HTTP协议选用的传输层协议是TCP
      HTTP协议应用:网页的获取,基于网站的数据传输;也被用作基于HTTP的数据传输
    特点:
        ①应用层协议,传输层使用tcp传输
        ②简单灵活,和多种语言对接方便
        ③无状态协议,不记录用户的通信内容
        ④成熟稳定'http1.1'
    工作模式:
        ①使用HTTP双方均遵循HTTP协议规定发送,接收消息体
        ②请求方根据协议组织请求内容发送给对方
        ③服务方,收到内容,按照协议解析
        ④请求方,收到回复,根据协议解析

2) HTTP请求格式:
    请求行 请求头 空行 请求体
    ①请求行
        请求种类   请求内容    协议版本
          GET        /      HTTP/1.1
        '请求种类':
            GET : 获取网络资源
            POST :提交一定的附加数据,得到返回结果
            HEAD :获取响应头
            PUT : 更新服务器资源
            DELETE :删除服务器资源
            CONNECT :预留
            TRACE :测试
            OPTIONS :获取服务器性能
        '请求内容:'
            浏览器地址栏中IP:端口'/'及'/'之后的内容
        备注:浏览器地址栏回车的请求类型:GET
    ②请求头
        以键值对的形式对请求信息进行描述;本阶段学习均采用浏览器自动填充的形式
    ③请求体
        提交具体的请求参数

3) HTTP响应格式:
    响应行 响应头 空行 响应体
    ②响应行:
        版本信息        响应码    附加信息
        HTTP/1.1     200        OK
        响应码:
            1xx   请求已接收,正在处理
            2xx   请求响应成功
            3xx   重定向,完成任务需要其他操作
            4xx   客户端错误
            5xx   服务端错误

            200  成功
            401  没有访问权限
            404  请求页面不存在
            500  服务器发生未知错误
            503  服务器暂时无法执行(可能因为网络原因或者并发量太大导致)
    ③响应头:
        以键值对的形式对响应信息进行具体描述
    ④响应体:
        将客户想要的内容进行返回

代码示例:运行程序,浏览器地址栏输入:127.0.0.1:8000像服务端发起请求;若不存在index.html文件,则触发IOError异常。

'''一个简易的http服务端程序
①响应浏览器http请求
②无论请求什么内容,都响应一个固定的静态页面
注意点:
①connfd.getpeername()获取客户端的IP及端口
②定义响应内容时,响应行,响应头,空行,响应体,用'\r\n'分隔每行内容
③请求字符串可以用splitlines()方法,获得请求行,请求头,空行,请求体组成的列表
'''
import socket

def handle_client(connfd):
    '''处理浏览器请求,并返回响应内容'''
    print("Connect to",connfd.getpeername())
    request = connfd.recv(4028).decode()
    requestHeaders = request.splitlines()
    for line in requestHeaders:
        # 打印请求行,请求头,空行及请求体
        print(line)
    try:
        f = open('index.html')
    except IOError:
        response = 'HTTP/1.1 404 not found\r\n' # 响应行
        response += '\r\n' # 空行,响应头选用默认值
        response += '******Sorry the page is not found******' #响应体
    else:
        response = 'HTTP/1.1 200 OK\r\n' # 响应行
        response += '\r\n' # 空行,响应头选用默认值
        # 文件流对象属于可迭代对象,同时也是迭代器
        for i in f:
            response += i #响应体
    finally:
        connfd.send(response.encode())
    connfd.close()    

def main():
    sockfd = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    sockfd.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)
    ADDR = ("0.0.0.0",8000)
    sockfd.bind(ADDR)
    sockfd.listen(5)
    while True:
        print("Waiting for connection...")
        connfd,addr = sockfd.accept()
        #拿到connfd新的套接字后,则立刻交由相应的函数处理浏览器请求
        handle_client(connfd)
    sockfd.close()

if __name__ == '__main__':
    main()

2.文件传输

1)服务端

'''文件服务器,发送文件给客户端'''
import socket

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
# 便于调试,设置套接字属性在服务端退出后,短时间恢复,端口可以立即被重用
s.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1)

ADDR = ("127.0.0.1",8888)
s.bind(ADDR)
s.listen(5)

while True:
    print("Waiting for connected...")
    connfd,addr = s.accept()
    print("Connect to",addr)
    # 由客户端指定要下载的文件
    file = connfd.recv(1024)
    with open(file,'rb') as f:
        while True:
            # 循环读取文件内容并发送
            data = f.read(1024)
            if not data:
                break
            connfd.send(data) #以二进制形式打开文件,读取的也是字节流
        connfd.close()

s.close()

2)客户端

'''实现从服务器下载文件'''
import socket

s = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
ADDR = ("127.0.0.1",8888)
# 向服务端发起连接请求
s.connect(ADDR)

# 输入服务端文件
src_file = input("Enter the file name you need:")
# 输入下载保存路径+文件名
des_file = input("Save to file as ?")
if des_file == '':
    des_file = '自定义一个路径' + src_file
else:
    des_file = '自定义一个路径' + des_file

s.send(src_file.encode())

with open(des_file,'wb') as des:
    while True:
        # 循环接收文件内容,并写入客户端文件
        data = s.recv(1024)
        if not data:
            break
        des.write(data)

s.close()

二.UDP数据报套接字的应用

局域网内发送和接收广播消息

1)发送端

'''发送广播消息的目标IP
sendto--->***.***.***.255
'''
import socket
from time import sleep

# 创建数据报套接字
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 设置套接字属性:允许接收和发送广播消息
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)

ADDR = ("广播地址",8888)

while True:
    try:
        data = b"This is a broadcast news!"
        # 发送广播消息
        s.sendto(data,ADDR)
        sleep(2)
    except KeyboardInterrupt:
        # Ctrl + C退出
        print("停止广播")
        break

s.close()

2)接收端

'''需要能够接收局域网内所有主机的广播消息
绑定IP为"0.0.0.0"
'''
import socket

# 创建数据报套接字
s = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# 设置套接字属性:允许接收和发送广播消息
s.setsockopt(socket.SOL_SOCKET,socket.SO_BROADCAST,1)

# 作为接收方,需要绑定IP地址
ADDR = ("0.0.0.0",8888)
s.bind(ADDR)

while True:
    try:
        # 接收广播消息
        data,addr = s.recvfrom(1024)
        print("Receive {} from {}".format(data.decode(),addr))
    except KeyboardInterrupt:
        # Ctrl + C退出
        print('停止接收广播消息!')
        break
    except Exception as e:
        print(e)

s.close() 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值