socket套接字编程(二)

UDP套接字广播

  • 广播定义:一端发送多点接收
  • 广播地址:每个网络的最大地址为发送广播的地址,向该地址发送,则网段内所有主机都能接收。

广播发送(broadcast_send.py)

from socket import *
from time import sleep

# 广播地址
dest = ('192.168.0.101', 9999)

s = socket(AF_INET, SOCK_DGRAM)

s.setsockopt(SOL_SOCKET, SO_BROADCAST, True)

data = '发送的广播信息'

while True:
    sleep(2)
    s.sendto(data.encode(), dest)

s.close()

广播接收(broadcast_recv.py)

from socket import *

s=socket(AF_INET, SOCK_DGRAM)

# 让套接字可以接收广播
s.setsockopt(SOL_SOCKET, SO_BROADCAST, True)

s.bind(('0.0.0.0', 9999))

while True:
    try:
        msg, addr = s.recvfrom(1024)
    except KeyboardInterrupt:
        break
    else:
        print(msg.decode())

s.close()

TCP套接字之HTTP传输

HTTP协议(超文本传输协议)

  1. 用途:网页获取,数据的传输
  2. 特点:
  • 应用层协议,传输层使用tcp传输
  • 简单,灵活,很多语言都有HTTP专门接口
  • 无状态,协议不记录传输内容
  • http1.1 支持持久连接,丰富了请求类型
  1. 网页请求过程
    【1】客户端(浏览器)通过tcp传输,发送http请求给服务端
    【2】服务端接收到http请求后进行解析
    【3】服务端处理请求内容,组织响应内容
    【4】服务端将响应内容以http响应格式发送给浏览器
    【5】浏览器接收到响应内容,解析展示
    在这里插入图片描述

HTTP请求(request)

  • 请求行(重点):具体的请求类别和请求内容
GET               /             HTTP/1.1

请求类别                   请求内容                         协议版本

  1. 请求类别:每个请求类别表示要做不同的事情,包括:
    【1】GET:获取网络资源
    【2】POST:提交一定的信息,得到反馈
    【3】HEAD:只获取网络资源的响应头(对请求资源的说明)
    【4】PUT:更新服务器资源
    【5】DELETE:删除服务器资源
    【6】CONNECT(无具体功能)
    【7】TRACE:测试
    【8】OPTIONS:获取服务器性能信息
  2. 请求内容:可以类比文件目录。/ 表示主页,/XXX 表示主页下的具体内容
  3. 协议版本:HTTP1.0/1.1(现在都用1.1)
  • 请求头:对请求的进行一步解释和描述
    Accept-Encoding:gzip(希望得到的编码格式)
  • 空行
  • 请求体:请求的参数或者提交的内容

HTTP响应(response)

响应格式:响应行,响应头,空行,响应体

  • 响应行:反馈基本的响应情况
HTTP/1.1         200            OK

    版本信息                  响应码                    附加信息

响应码:
1XX:提示信息,表示请求被接受
2XX:响应成功 200
3XX:响应需要进一步操作,重定向
4XX:客户端错误 404
5XX:服务器错误

  • 响应头:对响应内容的描述
    Content-Type:text/html
  • 空行
  • 响应体:响应的主体内容信息

模拟浏览器向服务器发送请求,服务器将响应结果发送给浏览器,并渲染浏览器页面。
服务器代码:

'''
服务端代码
'''
from socket import *

sockfd=socket()

sockfd.bind(('0.0.0.0', 8000))

sockfd.listen(5)

connfd, addr = sockfd.accept()
print('Connect from:', addr)

data = connfd.recv(1024) # 模拟接收请求
print(data.decode())

data="""HTTP/1.1 200 OK
Content-Type:text/html
 
<h1>hello world</h1>
"""
connfd.send(data.encode()) # 模拟发送响应信息

connfd.close()
sockfd.close()

在浏览器(客户端)地址栏输入请求URL:http://127.0.0.1:8000/(请求内容为空),请求结果如下:
在这里插入图片描述
服务器得到请求结果,并将响应结果发送回浏览器,浏览器解析HTML格式内容,并渲染页面如下:

在这里插入图片描述如果对上述响应内容(data)不想固定,而是读取HTML文件方式,可以参考我上传的文件

struct模块的使用

  1. 原理:将一组简单数据进行打包,转换为bytes格式发送。或者将一组bytes格式数据,进行解析。
  2. 接口使用

Struct(fmt)

功能:生成结构化对象
参数:fmt 定制的数据结构

st.pack(v1,v2,v3…)

功能:将一组数据按照指定格式打包转换为bytes
参数:要打包的数据
返回值:bytes字节串

st.unpack(bytes_data)

功能:将bytes字节串按照指定的格式解析
参数:要解析的字节串
返回值:解析后的内容

bytes_data = struct.pack(fmt,v1,v2,v3…)
d = struct.unpack(fmt,bytes_data)

说明:可以使用struct模块直接调用pack unpack。此时这两函数第一个参数为fmt,其余功能相同。

示例代码

import struct

# 以传递 1(int) zhangsan(8个string) 16(int) 78.5(float) 为例
# 打包
st = struct.Struct("i8sif")
data = st.pack(1, b'zhangsan', 16, 78.5)
print(data)
# b'\x01\x00\x00\x00zhangsan\x10\x00\x00\x00\x00\x00\x9dB'

# 解包
d = st.unpack(data)
print(d)
# (1, b'zhangsan', 16, 78.5)

数据结构转换码

在这里插入图片描述
小练习:

  1. 从客户端输入一个学生的 id 姓名 年龄 分数
  2. 将其发送到服务器,有服务端写入到一个文件中
  3. 每个信息占一行
  4. 数据传输使用udp完成

客户端代码:

from socket import *
import struct

sockfd = socket(AF_INET, SOCK_DGRAM)  # 数据报套接字

# 定制数据结构
st = struct.Struct("i32sif")

id = 1
while True:
    name = input('姓名>>').encode()
    age = int(input('年龄>>'))
    score = float(input('分数>>'))
    data = st.pack(id, name, age, score)  # 数据打包
    if not name or not age or not score:
        break
    sockfd.sendto(data, ('127.0.0.1', 8000))  # 发送数据
    id += 1
    msg, addr = sockfd.recvfrom(1024)
    print('From server:', msg.decode())

sockfd.close()

服务端代码:

from socket import *
import struct

sockfd = socket(AF_INET, SOCK_DGRAM)  # 数据报套接字
sockfd.bind(('0.0.0.0', 8000))  # 绑定地址

# 定制数据结构
st = struct.Struct("i32sif")

while True:
    data, addr = sockfd.recvfrom(1024)
    d = st.unpack(data)
    print(d)  # (1, b'zhangsan', 16, 78.5)
    f = open('demo.txt', 'a+')
    f.write('%d %s %d %.1f\n' % (d[0], d[1].decode(), d[2], d[3]))
    f.flush()
    sockfd.sendto(b'OK', addr)

f.close()
sockfd.close()

网络编程部分总结

需要掌握:

  1. 文件的读写操作(重要)
  2. 网络通信的基本知识
  3. TCP和UDP的通信(重要)
  4. http协议基础(重要)
  5. struct模块使用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值