python urllib、tcp、udp

 Urllib

# -*- coding: utf-8 -*-


from urllib.parse import *
import urllib

# 解析URL字符串
result = urlparse('http://www.crazyit.org:80/index.php;yeeku?name=fkit#frag')
print(result)
# 通过属性名和索引来获取URL的各部分
print('scheme:', result.scheme, result[0])
print('主机和端口:', result.netloc, result[1])
print('主机:', result.hostname)
print('端口:', result.port)
print('资源路径:', result.path, result[2])
print('参数:', result.params, result[3])
print('查询字符串:', result.query, result[4])
print('fragment:', result.fragment, result[5])
print(result.geturl())

# 恢复URL字符串
result1 = urlunparse(('http', 'www.crazyit.org:80', 'index.php', 'yeeku', 'name=fkit', 'frag'))  # 元组形式
print('url为: ', result1)

result2 = parse_qs('name=fkit&name=%E7%96%AF%E7%8B%82java&age=12')
print(result2)  # 返回dict
print(urlencode(result2))
result3 = parse_qsl('name=fkit&name=%E7%96%AF%E7%8B%82java&age=12')  # l 代表list
print(result3)  # 返回list
print(urlencode(result3))

# urljoin() 函数负责将两个URL拼接在一起,返回代表绝对地址的URL。
# 被拼接的URL只是一个相对路径path(不以斜线开头),那么该URL将会被拼凑到base之后,如果base本身包含path部分,则用拼接的部分替换base所包含的path部分。
# 被拼接的URL是一个根路径path(以单斜线开头),那么该URL将会被拼接到base的域名之后。
# 被拼接的URL是一个绝对路径(以双斜线开头),那么该URL将会被拼接到base的scheme之后
# 被拼接URL不以斜线开头
result = urljoin('http://www.crazyit.org/users/login.html', 'help.html')
print(result)  # http://www.crazyit.org/users/help.html
result = urljoin('http://www.crazyit.org/users/login.html', 'book/list.html')
print(result)  # http://www.crazyit.org/users/book/list.html
# 被拼接URL以斜线(代表根路径path)开头
result = urljoin('http://www.crazyit.org/users/login.html', '/help.html')
print(result)  # http://www.crazyit.org/help.html
# 被拼接URL以双斜线(代表绝对URL)开头
result = urljoin('http://www.crazyit.org/users/login.html', '//help.html')
print(result)  # http://help.html

# 被解析的 URL 以双斜线(//)开头,那么 urlparse() 函数可以识别出主机,只是缺少 scheme 部分。

result = urlparse('//www.crazyit.org:80/index.php')
print('scheme:', result.scheme, result[0])
print('主机和端口:', result.netloc, result[1])
print('资源路径:', result.path, result[2])
print('-----------------')
# 被解析的 URL 既没有 scheme,也没有以双斜线(//)开头,那么 urlparse() 函数将会把这些 URL 都当成资源路径。
result = urlparse('www.crazyit.org:80/index.php')
print('scheme:', result.scheme, result[0])
print('主机和端口:', result.netloc, result[1])
print('资源路径:', result.path, result[2])
print('++++++++++++++++++')
# -*- coding: utf-8 -*-

from urllib.request import *
import urllib.parse

# with 所求值的对象必须有一个enter()方法,一个exit()方法
# with**后面的语句被求值后,返回对象的**__enter__()方法被调用 ,方法的返回值被赋值给as 后面的变量
# with后面的代码块全部执行完之后,将调用前面返回对象的exit()方法

# urlopen() 打开URL指定的资源,并从中读取数据
# 打开URL对应的资源
result = urlopen('http://www.crazyit.org/index.php')
# 按字节读取数据
data = result.read(326)
# 将字节数据恢复成字符串
print(data.decode('utf-8'))

# 用context.manager来管理打开的URL资源
with urlopen('http://www.crazyit.org/index.php') as f:
    # 按字节读取数据
    data = f.read(326)
    # 将字节数据恢复成字符串
    print(data.decode('utf-8'))

# 在使用URLopen函数时,可以通过data属性向被请求的URL发送数据。
# with urlopen(url='http://localhost:8888/test/test',
#              data='测试数据'.encode('utf-8')) as f:
#     # 读取服务器全部相应
#     print(f.read().decode('utf-8'))
# 服务端需要进行接收相应

# 使用URLopen()函数向服务器页面发送GET请求参数,则无须使用data属性,直接把请求参数附加在URL之后即可
params = urllib.parse.urlencode({'name': 'fkit', 'password': '123888'})
# 将请求参数添加到url的后面去
url = 'http://localhost:8888/test/get.jsp?%s' % params
with urlopen(url=url) as f:
    # 读取服务器全部响应
    print(f.read().decode('utf-8'))


params = 'put请求数据'.encode('utf-8')
# 创建Request对象,设置使用PUT请求
req = Request(url='http://localhost:8888/test/put', data=params, method='PUT')
with urlopen(req) as f:
    print(f.status)
    print(f.read().decode('utf-8'))

TCP通信协议

# -*- coding: utf-8 -*-

import socket
# 服务端

'''
socket的TCP协议通信的 服务器端
'''
# 实例化创建socket对象,默认为TCP协议类型通信
s = socket.socket()
host = socket.gethostname()  # 获取计算机全名
port = 1234  # 指定计算机端口号
s.bind((host, port))  # 服务器首次调用 bind方法绑定主机和端口,
s.listen(2)  # 服务器端其次调用 listen方法来监听特定的地址

# 循环调用socket的 accept()方法接受来自客户端的连接
while True:
    # 服务器端套接字开始监听后,就可接受客户端连接了
    # accept方法将同步阻断等待到客户端连接到来为止,然后返回一个(client,address)的元组
    # 返回的元组其中client是一个客户端套接字,address是前面解释过的地址
    c, addr = s.accept()
    print(c)
    print('连接地址: ', addr)
    # 注意:传输数据,套接字提供两个方法:send 和 recv,分别表示发送和接受数据
    c.send('你好,服务端向你发来问候'.encode('utf-8'))   # send方法发送数据,注意编码方式
    c.close()

# -*- coding: utf-8 -*-

import socket
# 客户端
''' 
客户端调用connect()方法连接远程服务器
'''

s = socket.socket()
host = socket.gethostname()
port = 1234
s.connect((host, port))

# 调用recv方法获取服务端发送的消息并输出
print(s.recv(1024).decode('utf-8'))

多线程进行通信

# -*- coding: utf-8 -*-

import socket
import threading

# 列表保存所有的socket
socket_list = []

ss = socket.socket()
ss.bind(('192.168.50.60', 1235))  # 绑定本机主机 和端口
ss.listen()  # 开始监听来自客户端的链接


def read_from_client(s):
    # 定义函数,用于尝试接收数据,如果没有接收到数据则说明此通信段关闭,从列表中删除此通信客户端。
    try:
        return s.recv(2048).decode('utf-8')
    # 如果捕获到异常,则表明该socket对应的客户端已经关闭,删除该socket
    except:
        socket_list.remove(s)


def server_target(s):
    # 该函数将会作为线程执行的 target,负责处理每个 socket的通信服务器端
    try:
        # 循环不断的从 socket 中读取 来自客户端发送来的数据
        while True:
            content = read_from_client(s)
            print(content)
            if content is None:
                break
            # 当服务器端线程读取到客户端数据后,程序遍历 socket_list列表,列表中的每个 socket 都发送一次
            for client_s in socket_list:
                client_s.send(content.encode('utf-8'))
    except Exception as e:
        print(e.strerror)


# 循环不断准备接收来自客户端的连接,并为每一个客户启动一个线程服务
while True:
    s, addr = ss.accept()  # 准备接收来自客户端的连接,此代码会阻塞,一直等待别人的连接
    socket_list.append(s)  # 将socket加入socket_list列表里保存,然后启动线程
    print(socket_list)
    # 接收到客户端连接后,就启动一个线程为该客户端服务
    threading.Thread(target=server_target, args=(s, )).start()

# -*- coding: utf-8 -*-

import socket
import threading


s = socket.socket()
# 服务端所在地的 ip和端口
s.connect(('192.168.50.60', 1235))


# 读取服务端发送的数据
def read_from_server(s):
    while True:
        print(s.recv(2048).decode('utf-8'))


# 客户端启动读取服务端发送数据的线程
threading.Thread(target=read_from_server, args=(s, )).start()
while True:
    line = input('')
    if line is None or line == 'exit':
        break
    # 发送用户输入的内容
    s.send(line.encode('utf-8'))

UDP通信协议

# -*- coding: utf-8 -*-

# type=SOCK_DGRAM  创建基于UDP协议的socket
# socket.sendto(bytes,address)  发送数据。将bytes数据发送到address地址
# socket.recvfrom(bufsize[, flags])  接收数据。该方法可以同时返回 socket 中的数据和数据来源地址

# UDP协议进行网络通信时,双方都需要建立一个socket对象,用于接收或者发送数据报
# 通常具有固定 ip 地址和端口的socket对象所在的程序被称为服务器,socket 应该调用bind() 方法被绑定到指定 IP 地址和端口,客户端通过ip地址与端口号同服务端建立连接后,才能向其发送数据报
# UDP协议适用于一次只传输少量数据、对可靠性要求不高的应用环境
# TCP协议面向连接的通信协议,UDP面向非连接的协议,没有建立连接的过程,通信效率高,可靠性低

import socket

books = ('大主宰', '武动苍穹', '遮天', '完美世界', '斗破苍穹', '斗罗大陆')

ss = socket.socket(type=socket.SOCK_DGRAM)  # 创建基于UDP通信协议的socket
ss.bind(('192.168.50.60', 123))

for i in range(100):
    # socket的UDP协议通信的 recvfrom方法 接收数据,可以同时返回socket中的数据和数据来源地址
    data, addr = ss.recvfrom(4096)  # 4096  数据报的大小最大为4KB  4096Byte(字节)
    print(data.decode('utf-8'))
    send_data = books[i % 4].encode('utf-8')  # 求余  定义服务器端发送的数据报内容
    # socket的UDP协议通信的 sendto方法 发送数据到指定地址
    ss.sendto(send_data, addr)
ss.close()
# -*- coding: utf-8 -*-

# 客户端循环不断读取用户的输入内容,通过数据报发送出去

import socket

s = socket.socket(type=socket.SOCK_DGRAM)

while True:
    line = input('')
    if line is None or line == 'exit':
        break
    data = line.encode('utf-8')
    s.sendto(data, (socket.gethostname(), 123))
    data1 = s.recv(4096)
    print(data1.decode('utf-8'))
s.close()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值