网络编程、聊天室、发邮件和短信

本文通过聊天室实例介绍Python网络编程的基础知识,包括TCP和UDP协议的应用,并演示如何使用socket库搭建服务器与客户端,还展示了如何利用多线程实现并发处理及邮件发送等功能。
# webbrowser  
#socketserver 比socket稍微好用一点
#decompose 分解  遇到复杂问题的解决方法
#端口1025-65535之间的端口
#Python命令行参数 - sys.argv 可以匹配到系统的ip和给定端口
#TCP - Transfer Control Protocol
#UDP - User Datagram Protocol

网络编程——聊天室——服务器

from socket import socket
from threading import Thread


def main():

    class ClientHander(Thread):

        def __init__(self, client):
            super().__init__()
            self._client = client

        def run(self):
            try:
                while True:
                    try:
                        data = self._client.recv(1024)

                        for client in clients:
                            if client != self._client:
                                client.send(data)
                        if data.decode('utf-8') == 'byebye':
                            clients.remove(self._client)
                            self._client.close()
                            break
                    except Exception as e:
                        print(e)
                        clients.remove(self._client)
                        break
            except Exception as e:
                print(e)


    server = socket()
    # Python命令行参数 - sys.argv 可以匹配到系统的ip和给定端口
    server.bind(('ip地址', 12345))
    server.listen(512)
    print('正在监听...')
    clients = []
    while True:
        curr_client, addr = server.accept()
        # 将所有接进来的人保存起来
        clients.append(curr_client)
        # 将每一个客户端都放进一个线程中
        ClientHander(curr_client).start()


if __name__ == '__main__':
    main()

聊天室客户端

from socket import socket
from threading import Thread


def main():

    class RefreshScreenThread(Thread):

        def __init__(self, client):
            super().__init__()
            self._client = client

        def run(self):
            while running:
                data = self._client.recv(1024)
                print(data.decode('utf-8'))

    nickname = input('请输入你的昵称:')
    myclient = socket()
    myclient.connect(('ip地址', 12345))
    running = True
    RefreshScreenThread(myclient).start()
    while True:
        content = input('请发言:')
        if content != 'byebye':
            content = nickname + ':' + content
        myclient.send(content.encode('utf-8'))
        if content == 'byebye':
            running = False
            break


if __name__ == '__main__':
    main()

UDP协议下的发送端

  • 不能保证可靠通信
  • 发送端切片,接收端要组装
  • 如果做应用,最好自定义协议,以便可以更好解析数据
from socket import socket, SOCK_DGRAM
#from time import sleep


def main():
    sender = socket(type=SOCK_DGRAM) #UDP用户数据报协议
    with open('mm.jpg', 'rb') as f:
        data = f.read()
    data_len = len(data) #文件的大小
    total = 0
    while total < data_len:    #切片发送
        sender.sendto(data[total:total + 1024], ('ip地址', 6789))
        total += 1024
        #sleep(0.01)  可以让网卡有更多时间来处理


if __name__ == '__main__':
    main()

接收端

from socket import socket,SOCK_DGRAM
#用UDP传输数据

def main():
    receiver = socket(type=SOCK_DGRAM)
    receiver.bind(('ip地址', 6789))
    data = bytes()  # 表示二进制数据
    while True:
        seg,addr = receiver.recvfrom(1024)  # 接收的缓冲区,返回的是一个元组数据片段和地址
        data += seg
        if len(seg) < 1024:#有bug如果文件正好是1024的倍数,则判断失败
            break
    with open('hello.jpg', 'wb') as f:
        f.write(data)
    print('图片已接收')


if __name__ == '__main__':
    main()

发送邮件

from email.mime.text import MIMEText
from smtplib import SMTP


def main():
    sender = SMTP('smtp.163.com')  # 发送邮件服务器
    sender.login('邮箱', '授权码') #邮箱和授权码
    content ="""
    给你讲个笑话吧
    一个男孩去找自己的同学,在同学家的门口看见一只大狗。同学在门内
    嚷:“你怎么还不进来?”男孩:“这只狗咬不咬人?”同学:“我们
    也很想知道,因为它是刚刚才来的!”
    此致,敬礼!
    wxz 即日

    """
    #  多行字符串输入  邮件内容
    #MIME - Multipurpose Internet Mail Extension  多用途网络邮件扩展
    message = MIMEText(content, 'plain', 'utf-8')   #plain表示普通文本
    message['Subject'] = '好久不见甚是想念'      # 邮件主题
    sender.sendmail('发送者邮箱', ['接收者邮箱'], message.as_string())
    # 第一参数是发件邮箱,第二个是收件邮箱,多个邮箱都可以放在列表里,最后参数是变成字符串
    print('邮件发送成功')

if __name__ == '__main__':
    main()
## 发送邮件加附件
from email.mime.multipart import MIMEMultipart
from email.mime.text import MIMEText
from smtplib import SMTP


def main():
    sender = SMTP('smtp.163.com')  # 发送邮件服务器
    sender.login('邮箱', '授权码')  # 邮箱和授权码
    message = MIMEMultipart()
    message['From'] = 'wxz'  # 发送者昵称
    message['To'] = 'hh'  # 收件者昵称
    message['Cc'] = '抄送者邮箱'  # 抄送
    message['subject'] = '请查收附件中的数据'
    text_msg = MIMEText('附件中有本月关键数据请查收', 'plain', 'utf-8')
    message.attach(text_msg)
    att2 = MIMEText(open('hello.docx', 'rb').read(), 'base64', 'utf-8')
    att2['Content-Type'] = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
    # 可以去网上搜文件后缀加MIME的类型比如docx的MIME类型
    att2['Content-Disposition'] = 'attachment;filename=hello.docx'
    # attachment:表示是附件 附件的名字
    message.attach(att2)
    sender.sendmail('发送者邮箱', '接收者邮箱', message.as_string())
    print('邮件发送成功')


if __name__ == '__main__':
    main()
#   %编码,晚自习自己科普 urlencode 将中文转为百分号编码
import http.client           #httplib改这个
import urllib
import random

host = "106.ihuyi.com "
sms_send_uri = "/webservice/sms.php?method=Submit"

# 用户名是登录用户中心->验证码短信->产品总览->APIID
account = "C*******"
# 密码 查看密码请登录用户中心->验证码短信->产品总览->APIKEY
password = "d4bc030d*************"


def send_sms(text, mobile):
    params = urllib.parse.urlencode(
        {'account': account, 'password': password, 'content': text, 'mobile': mobile, 'format': 'json'})
    headers = {"Content-type": "application/x-www-form-urlencoded", "Accept": "text/plain"}
    conn = http.client.HTTPConnection(host, port=80, timeout=30)
    conn.request("POST", sms_send_uri, params, headers) # POST发送消息
    response = conn.getresponse()
    response_str = response.read()
    conn.close()
    return response_str


if __name__ == '__main__':
    mobile = "157*******"
    #生成一个0-9的数字组成的随机验证码
    Random6 = str(random.randint(0,9)) + str(random.randint(0,9))+str(random.randint(0,9))+str(random.randint(0,9))+str(random.randint(0,9))+str(random.randint(0,9))
    print(Random6)
    text = ("您的验证码是:%i。请不要把验证码泄露给其他人。" % int(Random6))

    print(send_sms(text, mobile))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值