Category - 班级课件

2022-06-26 09:14:42    11    0    0

服务端(chat_server.py)

  1. import json
  2. import socket
  3. import traceback
  4. online_users = {}
  5. def decode_msg(msg):
  6. return json.loads(msg.decode('utf-8'))
  7. def encode_msg(msg):
  8. return json.dumps(msg).encode('utf-8')
  9. server_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  10. server_socket.bind(('localhost', 8888))
  11. while True:
  12. try:
  13. recv_message, recv_address = server_socket.recvfrom(1024)
  14. print("收到用户消息: %s, 网络地址 %s" % (recv_message, recv_address))
  15. recv_message = decode_msg(recv_message)
  16. msg_type = recv_message['type']
  17. if msg_type == 'login':
  18. recv_user_name = recv_message['user']
  19. online_users[recv_user_name] = recv_address
  20. for user_name, address in online_users.items():
  21. send_message = {'type': 'online', 'all_users': online_users, 'user': recv_user_name}
  22. server_socket.sendto(encode_msg(send_message), address)
  23. elif msg_type == 'quit':
2022-05-22 08:12:28    7    0    0

UDP编程

TCP用于建立可靠连接,并且通信双方可以以流的形式发送数据。相对于TCP,UDP面向无连接的协议。

使用UDP协议时不需要建立连接,只需要知道对方的IP地址和端口号就可以直接发送数据包。但是发送的数据包是否能到达就不 知道了。

虽然用UDP传输数据不可靠,但是优点是速度快。对于不要求可靠到达的数据可以使用UDP协议。

title

下面来看如何通过UDP协议传输数据。和TCP类似,使用UDP的通信双方也分为客户端和服务器。服务器首先需要绑定端口, 操作如下:

title

创建socket时,SOCK_DGRAM指定了socket的类型是UDP。绑定端口和TCP一样,不过不需要调用listen()方法,而是直接接 收来自任何客户端的数据,操作如下:

title

recvfrom()方法返回数据和客户端的地址与端口。这样,服务器收到数据后,直接调用sendto()就可以把数据用UDP发送给客户 端。

客户端使用UDP时,首先仍然是创建基于UDP的socket,然后不需要调用connect(),直接通过sendto()给服务器发送数据,操 作如下:

title

多线程

进程与线程

什么是线程,什么是进程?

进程是程序(软件,应用)的一个执行实例,每个运行中的程序,可以同时创建多个进程,但至少要有一个。每个进程都提供执 行程序所需的所有资源,都有一个虚拟的地址空间、可执行的代码、操作系统的接口、安全的上下文(记录启动该进程的用户和 权限等等)、唯一的进程ID、环境变量、优先级类、最小和最大的工作空间(内存空间)。进程可以包含线程,并且每个进程 必须有至少一个线程。每个进程启动时都会最先产生一个线程,即主线程,然后主线程会再创建其他的子线程。

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指 令指针(PC),寄存器集合和堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不独 立拥有系统资源,但它可与同属一个进程的其它线程共享该进程所拥有的全部资源。每一个应用程序都至少有一个进程和一个线 程。在单个程序中同时运行多个线程完成不同的被划分成一块

2022-05-15 08:29:46    6    0    0

前面我们了解了TCP/IP协议、IP地址和端口的基本概念,下面我们开始了解网络编程。

网络编程中有一个基本组件——套接字(socket)。套接字主要是两个程序之间的“信息通道”。 程序(通过网络连接)可能 分布在不同的计算机上,通过套接字相互发送信息。

socket是网络编程的一个抽象概念。通常我们用一个socket表示“打开了一个网络连接”,而打开一个socket需要知道目标计 算机的IP地址和端口号,并且指定协议类型。

大多数连接都是可靠的TCP连接。创建TCP连接时,主动发起连接的是客户端,被动响应连接的是服务器。

socket编程交互模型如下图所示

title

服务器编程

服务器编程首先要绑定一个端口,监听来自其他客户端的连接。如果某个客户端发起连接了,服务器就与该客户端建立socket 连接,随后的通信就靠这个socket连接了。

服务器会打开固定端口监听,每发起一个客户端连接,就创建该socket连接。由于服务器有大量来自客户端的连接,因此要能 够区分一个socket连接是和哪个客户端绑定的。确定4项唯一的socket依赖:服务器地址、服务器端口、客户端地址、客户端端 口。

title

服务端创建流程

一般来说,建立服务器连接需要6个步骤。

创建socket对象

在Python中, import socket 后,用 socket.socket() 方法来创建套接字,语法格式如下

  1. s = socket.socket([family[, type[, proto]]])

参数说明:

  • family: 套接字家族,可以使 AF_UNIX 或者 AF_INET ,默认 AF_INET
  • type: 套接字类型,根据是面向连接的还是非连接分为 SOCK_STREAM 或 SOCK_DGRAM ,也就是 TCP 和 UDP 的区别。默 认 SOCK_STREAM
  • protocol: 一般不填默认为0。

直接socket.socket(),则全部使用默认值。

下面是具体的参数定义:

title

绑定地址

将socket绑定(指派)到指定地址上

  1. socket.bind(address)

address必须是一个双元素元组((host,

2022-05-08 08:24:59    59    0    0

计算机网络基础

计算机网络是独立自主的计算机互联而成的系统的总称,组建计算机网络最主要的目的是实现多台计算机之间的通信和资源共 享。

今天计算机网络中的设备和计算机网络的用户已经多得不可计数,而计算机网络也可以称得上是一个“复杂巨系统”.

计算机网络发展史

1960s - 美国国防部ARPANET (阿帕网络(Advanced Research Project Agency Network))项目问世,奠定了分组交 换网络的基础。

title

1980s - 国际标准化组织(ISO)发布OSI/RM,奠定了网络技术标准化的基础。

title

1990s - 英国人蒂姆·伯纳斯-李发明了图形化的浏览器,浏览器的简单易用性使得计算机网络迅速被普及。

在没有浏览器的年代,上网是这样的。

title

有了浏览器以后,上网是这样的。

title

TCP/IP模型

实现网络通信的基础是网络通信协议,这些协议通常是由互联网工程任务组 (IETF)制定的。

所谓“协议”就是通信计算机双方必须共同遵从的一组约定,例如怎样建立连接、怎样互相识别等,网络协议的三要素是:语 法、语义和时序。

构成我们今天使用的Internet的基础的是TCP/IP协议族,所谓协议族就是一系列的协议及其构成的通信模型,我们通常也把这套 东西称为TCP/IP模型。

与国际标准化组织发布的OSI/RM这个七层模型不同,TCP/IP是一个四层模型,也就是说,该模型将我们使用的网络从逻辑上分 解为四个层次,自底向上依次是:网络接口层、网络层、传输层和应用层,如下图所示。

title

IP通常被翻译为网际协议,它服务于网络层,主要实现了寻址和路由的功能。

接入网络的每一台主机都需要有自己的IP地址,IP地址就是主机在计算机网络上的身份标识

title

当然由于IPv4地址的匮乏,我们平常在家里、办公室以及其他可以接入网络的公共区域上网时获得的IP地址并不是全球唯一的IP 地址,而是一个局域网(LAN)中的内部IP地址,通过网络地址转换(NAT)服务我们也可以实现对网络的访问。

title

计算机网络上有大量的被我们称为“路由器”的网络中继设备,它们会存储转发我们发送到网络上的数据分组,让从源头发出的 数据最终能够

2022-04-10 08:23:05    16    0    0

控件通用方法

after方法

定时任务, 让控件在 delay_ms 毫秒后去调用函数 func , 其中 args 为函数的参数

格式为:

  1. w.after(delay_ms, func=None, *args)

方法返回值为int类型的标识符, 可以使用 .after_cancel() 方法取消定时任务

bind方法

向控件添加一个事件绑定

格式为:

  1. w.bind(sequence=None, func=None, add=None)

参数 sequence 指的是事件名, func 是回调函数, 当该事件已经绑定到一个回调函数上, 默认情况会使用新函数覆盖老函数, 使 用 add='+' 保留新旧两个

事件格式: <[modifier-]...type[-detail]>

title

事件名如何表示:

  • 鼠标事件:
    Button: 代表所有鼠标键的点击
    Button-1: 代表鼠标左键的点击
    Button-2/3: 代表鼠标右键的点击
    ButtonPress: 鼠标按下事件
    ButtonPress-1: 代表鼠标左键的点击
    ButtonPress-2/3: 代表鼠标右键的点击
    ButtonRelease: 鼠标抬起事件
    ButtonRelease-1: 代表鼠标左键的点击
    ButtonRelease-2/3: 代表鼠标右键的点击
  • 按键事件:
    KeyPress: 按键按下
    KeyRelease: 按键抬起
    KeyPress-a: 按字母按下事件, 区分大小写
    Control-Shift-KeyPress-H: 组合键
    KeyPress-Return: 回车键Enter

函数格式:

  1. def 函数名(事件参数)

如:

2022-03-27 08:04:44    16    0    0

tkinter知识

控制变量

tkinter 中的控制变量,可以在不同的部件中共用,使用 set (value) 方法设置变量值后,所有相关的部件会在屏幕更新時自动更 新;控制变量的建立必须使用以下三种类别之一:

title

控制变量的方法

title

Entry文本输入控件

文本框组件常用的方法:

  • delete(first, last=None) 从组件中删除字符, 从 first 索引位置开始, 到 last (不包含)索引位置结束. 如果 last 参数没有的话, 只删除 first 一个字符, 例如: text.delete(10); text.delte(10,20); text.delete(0,tkinter.END);text.delete(0, 'end')
  • insert(index, s) 在 index 索引位置前插入字符串s, text.insert(0,"sss")
  • get() 将组建当前的内容作为字符串返回, text.get()

entry的索引有以下几种表示方式:

  • 普通的python索引表示法: 从0开始的整数
  • 常量 tkinter.END 代表文本框文本的最后位置
  • 常量 tkinter.INSERT 代表当前光标的位置
  • 常量 tkinter.ANCHOR 代表当前选中位置的第一个字符前(有选中)

Random模块

该模块实现了各种分布的伪随机数生成器。

几乎所有模块函数都依赖于基本函数 random() ,它在半开放区间 [0.0,1.0) 内均匀生成随机浮点数。

  1. import random

常用的方法如下:

  • random.randrange([start], stop[, step]),从指定范围内,按指定基数递增的集合中 获取一个随机数。

如:random.randrange(10, 100, 2),结果相当于从[10, 12, 14, 16, … 96, 98]序列中获取一个随机数。

  • random.choice从序列中获取一个随机元素。其函数原型为:random.choice(sequence)。参数sequence表示一个有序 类型。

这里要说明 一下:sequ

2022-03-20 08:16:29    16    0    0

tkinter组件

Radiobutton单选框

单选按钮控件;显示一个单选的按钮状态

单选按钮控件仅允许用户选择单一的选项值,各个选项值之间是互斥的关系,因此只有一个选项可以被用户选择。

Radiobutton 控件通常都是成组出现的,所有控件都使用相同的变量。

语法格式如下:

  1. radio=tkinter.Radiobutton(master, options...)

例如:

  1. var_radio = tkinter.IntVar()
  2. radio = tkinter.Radiobutton(window, text="弱", disabledforeground='red', value=1, variable=var_radio)
  3. radio.grid(row=1, column=2)
  4. radio = tkinter.Radiobutton(window, text="中", disabledforeground='red', value=2, variable=var_radio)
  5. radio.grid(row=1, column=3)
  6. radio = tkinter.Radiobutton(window, text="强", disabledforeground='red', value=3, variable=var_radio)
  7. radio.grid(row=1, column=4)

Radiobutton 属性列表,如下所示:

  • text 单选框要显示的文本, 多行使用\n换行
  • textvariable 如果想要在程序运行时改变文本的值, 使用该选项替换text
  • height 高度, 指的是文本的行数
  • width 宽度
  • variable 存储单选框值的变量, 当单选框状态改变是,可以通过该变量获取选中单选框的值
  • value 单选框的值, 在单选框组里面唯一

注意:

radiobutton成组出现时: variable参数一定要是同一个, 并且value参数不能相同

Combobox组合框控件

Combobox 控件,也就是下拉菜单控件(或称复合框),该控件是列表控件的改进版,具有更加灵活的界面,因此其应

2022-03-13 08:22:51    46    0    0

Tkinter是什么

Tkinter 是使用 python 进行窗口视窗设计的模块。Tkinter模块(“Tk 接口”)是Python的标准Tk GUI工具包的接口。

Graphical User Interface 图形用户接口

tkinter是python 自带的, 可以编辑的GUI界面,我们可以用GUI 实现很多直观的功能,比如想开发一个计算器,如果只是一个 程序输入,输出窗口的话,是没用用户体验的。所有开发一个图像化的小窗口,就是必要的。

概念介绍

窗口和控件

在GUI编程中,顶层的根窗口对象包含组成GUI应用的所有小窗口对象,它们可以是文字标签、按钮、列表框等,这些独立的 GUI组件称为控件。当创建一个顶层窗口时,指的是需要一个地方来摆放所有的控件。

在Python中,一般用如下语句创建根窗口:

  1. import tkinter
  2. top=tkinter.Tk()

或者

  1. from tkinter import *
  2. top=Tk()

tkinter.Tk() 返回的对象通常称为根窗口

顶层窗口是那些在应用中独立显示的部分,GUI程序中可以有多个顶层窗口,但只能有一个根窗口。

件可以独立存在,也可以作为容器存在。如果一个控件包含其他控件,就可以称其为其他控件的父控件。若一个控件被其他控件 包含,则称其为那个控件的子控件,而父控件就称为包围它的容器控件。

控件有一些相关的行为,如按下按钮、将文本写入文本框等,这些行为称为事件,而GUI对这类事件的响应称为回调。

事件驱动处理

事件包括按下按钮及释放、鼠标移动、按回车键等。一个GUI应用从开始到结束就是通过整套事件体系来驱动的,这种方式称为 事件驱动处理。

布局管理器

tkinter有3种布局管理器,即Placer、Packer和Grid。

Placer是最原始的布局管理器,Placer的做法非常直接,只需提供控件的 大小和摆放位 置,然后管理器就会自动将其摆放好。但 这有一个问题,就是你必须对所有控件进行这些操作,这会加重编程开发者的负担,因为这些操作本应该是自动完成的

  1. btn.place(x=100,y=100)

Packer

2022-01-22 14:30:23    52    0    0

选择题

  • 1、有如下Python程序段:
  1. x,y=12,5
  2. if x % y==0:
  3. z=x/y
  4. print(x,"/",y,"=",z)
  5. else:
  6. z=y*x
  7. print(x,"*",y,"=",z)

程序段执行后,输出的结果为?( )

  1. Ax/y=2.4
  2. Bx*y=60
  3. C12/5=2.4
  4. D12*5=60
  • 2、下列创建元组的方法中不正确的是?( )
  1. At=(1,2,'信息'
  2. Bt=(1)
  3. Ct=('信息',)
  4. Dt='音乐','体育','美术'
  • 3、已知存在字典a中有多个键值对,以下指令可以清空字典并保留变量的是?( )
  1. Aa.remove()
  2. Ba.pop()
  3. Ca.clear()
  4. Ddel a
  • 4、列表a=[1,2,3,4,5,6,7,8,9],对列表进行切片操作,要想得到[3,5,7],以下切片正确的是?( )
  1. Aa[-7:-2:-2]
  2. Ba[2:7:2]
  3. Ca[3:7:2]
  4. Da[2:7:-2]
  • 5、alist=['cat','bat','cat','hat','cat'],执行下列代码,输出的结果是?( )
  1. alist.remove('cat')
  2. print(alist)
  1. A、['cat','bat','cat','hat','cat']
  2. B、['bat','cat','hat','cat']
  3. C、['bat','hat']
  4. D、['cat','bat','cat','hat']
  • 6、对于字典dic={1:2,'3':'d','sex':1,4:{'No':1,'name':'Mike'}},len(dic)的值是?( )
  1. A3
  2. B4
  3. C5
  4. D6
  • 7、对于元组tup=(1,2,3,4,5)执行的操作非法的是?( )
  1. Alen(tup)
  2. Bmax(tup)
  3. Cmin(tup)
  4. Dtup[1] = 6
  • 8、使用map函数可以实现列表数据元素类型的转换,而无需通过循环。则将列表L=['1','3','5','7','9']转换为列表[1,3,5,7,9]的函数写法为?( )
  1. Amap(int,L)
  2. Blist(map(i
2022-01-16 09:47:30    28    0    0

2/2