1,同时运行两个python程序的方法
2,socket编程初探
3,多线程编程初探
4,GUI编程tix部分控件的属性
5,Python的list类型
有这个问题的原因是:socket编程,通常是两个程序进行试验,server和client。之前搞了好长时间,使用vscode调试的时候发现一个IDE只能运行一个程序。
问题解决也很简单:开两个vscode。。。
socket最基本的编程模型:Server-Client模型(TCP链接)。
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- # 文件名:server.py
- import socket # 导入 socket 模块
- import sys
- s = socket.socket() # 创建 socket 对象
- host = socket.gethostname() # 获取本地主机名
- port = 33222 # 设置端口
- s.bind((host, port)) # 绑定端口
-
- s.listen(5) # 等待客户端连接
- while True:
- conn, addr = s.accept() # 建立客户端连接
- print(conn)
- print(addr)
- recvbuff = conn.recv(1024).decode()
- print(recvbuff)
- sendbuf = '已经链接'
- conn.send(sendbuf.encode())
-
- s.close() # 关闭连接
- conn.close()
- sys.exit()
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- # 文件名:client.py
-
- import socket # 导入 socket 模块
-
- c = socket.socket() # 创建 socket 对象
- host = socket.gethostname() # 获取本地主机名
- port = 33222 # 设置端口号
-
- c.connect((host, port))
- c.send('我是土豆!'.encode());
- print(c.recv(1024).decode())
- c.close()
服务端:
客户端:
由于本次练习的程序需要GUI窗口和socket编程两个过程(模块)。以我的知识,为了不让两个过程冲突,我认为需要使用多线程编程。
调用thread模块中的start_new_thread()函数来产生新线程。语法如下:
thread.start_new_thread ( function, args[, kwargs] )
参数说明:
由于要对对话框进行简单的设置,我这次需要用到以下几个控件属性
justify
定义对齐方式,可选值有:LEFT,RIGHT,CENTER,默认为 CENTER。
relief
边框样式,可选的有:FLAT、SUNKEN、RAISED、GROOVE、RIDGE。默认为 FLAT。
width
设置标签宽度,默认值是 0,自动计算,单位以像素计。
height
标签的高度,默认值是 0。
作为Server端接收方,要在Lable上显示从Client收到的数据,而且是积累数据。有几种方法:
本次是学习,所以就找了下Python是否有自己成熟的类或者对象,List符合要求
序列(List)是Python中最基本的数据结构。序列中的每个元素都分配一个数字 - 它的位置,或索引,第一个索引是0,第二个索引是1,依此类推。
Python有6个序列的内置类型,但最常见的是列表和元组。
创建一个列表,只要把逗号分隔的不同的数据项使用方括号括起来即可。如下所示:
- list1 = ['physics', 'chemistry', 1997, 2000]
- list2 = [1, 2, 3, 4, 5 ]
- list3 = ["a", "b", "c", "d"]
这个东西基本可以使用:先把Server每次从Client收到的数据存到List,显示的时候顺序打出来,放到Lable的text框中
服务端代码:
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- # 文件名:server.py
- import _thread
- from tkinter import GROOVE, RAISED, RIDGE, SUNKEN, LEFT, StringVar, tix
- import socket # 导入 socket 模块
- import sys
-
- recvbuff = 'hello world! \n你好,世界'
- listbuff = []
-
- conn = socket.socket()
- def recvfun():
- s = socket.socket() # 创建 socket 对象
- host = socket.gethostname() # 获取本地主机名
- port = 33222 # 设置端口
- s.bind((host, port)) # 绑定端口
- s.listen(5) # 等待客户端连接
- global conn
- global listbuff
- conn, addr = s.accept() # 建立客户端连接
- while True:
- l_test_buff = ''
- recvbuff = conn.recv(1024).decode()
- recvbuff = str(addr)+':'+recvbuff+'\n'
- listbuff.append(recvbuff)
- for recb1 in listbuff:
- l_test_buff = l_test_buff + recb1
- l_text.set(l_test_buff)
- return
-
- #创建线程处理收到的消息
- _thread.start_new_thread(recvfun)
-
- #def windows_init():
- mywin = tix.Tk()
- mywin.title("socket window Server")
-
- #定义StringVar
- l_text = StringVar()
- l_text.set(recvbuff)
- #初始化数据
- text = "hello world! \n你好,世界"
- l_text.set(text)
-
- #button2 myclean实现 清除Entry内容,并回复成原状
- def myclearn():
- text = "hello world! \n你好,世界"
- l_text.set(text)
- e_00.delete(0, "end")
- return
-
- #FLAT、SUNKEN、RAISED、GROOVE、RIDGE
- #l_00 = tix.Label(root, font=("微软雅黑", 12), width=40, height=10, relief=SUNKEN, bg='#FFFFFF') .set(recvbuff)
- #justify 定义对齐方式,可选值有:LEFT,RIGHT,CENTER,默认为 CENTER。
- l_00 = tix.Label(mywin, font=("微软雅黑", 12), relief=SUNKEN, justify=LEFT, width=40, height=10, textvariable=l_text)
- l_00.pack(pady=20)
-
- e_00 = tix.Entry(mywin, font=("微软雅黑", 12))
- e_00.pack(pady=20)
-
- #服务端暂时没用
- def sendmsg():
- text = e_00.get()
- #l_text.set(text)
- conn.send(text.encode())
- return
-
-
- b1 = tix.Button(mywin, text="发送", command=sendmsg)
- b1.pack(pady=10, side='left')
-
- b2 = tix.Button(mywin, text="清空", command=myclearn)
- b2.pack(before=b1, side='left', padx=70, pady=10)
-
-
- # 进入消息循环
- mywin.mainloop()
- #return
- #窗口
-
-
- #_thread.start_new_thread(windows_init)
-
- #windows_init()
-
-
客户端代码:
- #!/usr/bin/python
- # -*- coding: UTF-8 -*-
- # 文件名:server.py
- import _thread
- from tkinter import GROOVE, RAISED, RIDGE, SUNKEN, StringVar, tix
- import socket # 导入 socket 模块
- import sys
-
-
- recvbuff = 'hello world! \n你好,世界'
-
- def recvfun():
- s = socket.socket() # 创建 socket 对象
- host = socket.gethostname() # 获取本地主机名
- port = 33222 # 设置端口
- s.bind((host, port)) # 绑定端口
- s.listen(5) # 等待客户端连接
- while True:
- conn, addr = s.accept() # 建立客户端连接
- recvbuff = conn.recv(1024).decode()
- recvbuff = str(addr)+':'+recvbuff
- l_text.set(recvbuff)
- #print(recvbuff)#
- sendbuf = '已经连接!'
- conn.send(sendbuf.encode())
- return
-
- #_thread.start_new_thread(recvfun)
-
- #def windows_init():
- mywin = tix.Tk()
- mywin.title("socket window Client")
-
- #定义StringVar
- l_text = StringVar()
- l_text.set(recvbuff)
- #初始化数据
- text = "hello world! \n你好,世界"
- l_text.set(text)
-
- c = socket.socket() # 创建 socket 对象
- host = socket.gethostname() # 获取本地主机名
- port = 33222 # 设置端口号
- c.connect((host, port))
-
- #button2 myclean实现 清除Entry内容,并回复成原状
- def myclearn():
- text = "hello world! \n你好,世界"
- l_text.set(text)
- e_00.delete(0, "end")
- global c
- c.close()
- return
-
- #FLAT、SUNKEN、RAISED、GROOVE、RIDGE
-
- #l_00 = tix.Label(root, font=("微软雅黑", 12), width=40, height=10, relief=SUNKEN, bg='#FFFFFF') .set(recvbuff)
-
-
- l_00 = tix.Label(mywin, font=("微软雅黑", 12), relief=SUNKEN, width=40, height=10, textvariable=l_text)
- l_00.pack(pady=20)
-
- e_00 = tix.Entry(mywin, font=("微软雅黑", 12))
- e_00.pack(pady=20)
-
-
-
- def sendmsg():
- global c
- text = e_00.get()
- c.send(text.encode());
- return
-
-
- b1 = tix.Button(mywin, text="发送", command=sendmsg)
- b1.pack(pady=10, side='left')
-
- b2 = tix.Button(mywin, text="清空", command=myclearn)
- b2.pack(before=b1, side='left', padx=70, pady=10)
-
-
- # 进入消息循环
- mywin.mainloop()
- #return
- #窗口
-
-
- #_thread.start_new_thread(windows_init)
-
- #windows_init()
-
-
运行结果:
左边Server,右边Client