python TCP与UDP连接模型(包含案列及源代码)

1、TCP与UDP连接模型

    (1)TCP模型  

 (2)UDP模型

  2、TCP连接代码

    (1)服务端

from socket import *
IP = '0.0.0.0' #标识绑定主机所有网络接口IP地址
PORT = 50000   #端口号
BUFLEN=512     #缓冲区

#实例化一个socket对象
#AF_INET标识网络层使用IP协议
#AF_STREAM标识传输层使用TCP协议
listensocket = socket(AF_INET,SOCK_STREAM)

#socket绑定地址和端口
listensocket.bind((IP,PORT))

#使socket处于监听状态,等待客户端的连接请求
#参数5表示最多接收等待 连接的个数
listensocket.listen(5)
print(f"服务器端启动成功,在{PORT}端口等待连接")

#返回元组信息
datasocket1,addr = listensocket.accept()
print("接收一个客户端连接:",addr)

while True:
    reved = data1.socket.rev(BUFLEN)
    if not reved:
        break
    info = reved.decode()
    print("接收方信息:{info}")

    datasocket1.send(f"服务器接收到的信息:{info}".encode())

(2)客户端

from socket import *

IP = '127.0.0.1'
SERVER_PORT = 50000
BUFLEN = 512

#实例化一个socket对象
#AF_INET标识网络层使用IP协议
#AF_STREAM标识传输层使用TCP协议
datasocket = socket(AF_INET,SOCK_STREAM)
datasocket.connect((IP,SERVER_PORT))

while True:
    tosend = input(">>>")
    if tosend == 'exit':
        break
    
    datasocket.send(tosend.encode())

    recved = datasocket.resv(BUFLEN)
    
    if not recved:
        break;
    print(recved.decode())

datasocket.close()

3、备份服务器案例

        利用TCP通信协议,采用可视化界面实现远程备份管理工具

程序流程图:

服务端:

from tkinter import *
from tkinter.ttk import *
import  socket
import struct
import os
import pickle
BAK_PATH = r'E:\bak' #设定默认备份目录


#接收文件信息的函数
def recv_unit_data(clnt,infos_len):
    data = b''
    if 0 < infos_len <=1024:
        data += clnt.recv(infos_len)
    else:
        while True:
            if infos_len > 1024:
                data +=clnt.recv(1024)
                infos_len -= 1024
            else:
                data += clnt.recv(infos_len)
                break
    return data


#获取文件信息函数
def get_files_info(clnt):
    fmt_str = 'Q'
    headsize = struct.calcsize(fmt_str)  #计算出长整型的长度
    data = clnt.recv(headsize)
    infos_len = struct.unpack(fmt_str,data)[0]
    data = recv_unit_data(clnt,infos_len)
    return pickle.loads(data)


def mk_path(filepath):
    paths = filepath.split(os.path.sep)[:-1]
    p = BAK_PATH
    for path in paths:
        p = os.path.join(p,path)
        if not os.path.exists(p):
            os.mkdir(p)


def recv_file(clnt,infos_len,filepath):
    mk_path(filepath)
    filepath = os.path.join(BAK_PATH,filepath)
    f = open(filepath,"wb+")
    try:
        if 0 < infos_len <= 1024:
            data = clnt.recv(infos_len)
            f.write(data)
        else:
            while True:
                if infos_len > 1024:
                    data = clnt.recv(1024)
                    f.write(data)
                    infos_len -= 1024
                else:
                    data = clnt.recv(infos_len)
                    f.write(data)
                    break
    except:
        print('error')
    else:
        return True
    finally:
        f.close()


def send_echo(clnt,res):
    if res:
        clnt.sendall(b'success')
    else:
        clnt.sendall(b'failure')




def start(host,port):
    if not os.path.exists(BAK_PATH):
        os.mkdir(BAK_PATH)
    st = socket.socket()
    st.bind((host,port))
    st.listen(1)
    client,addr = st.accept()
    file_lst = get_files_info(client)
    for size,filepath in file_lst:
        res = recv_file(client,size,filepath)
        send_echo(client,res)


    client.close()
    st.close()


#定义窗体类
class MyFrame(Frame):


    def __init__(self,root):
        super().__init__(root)
        self.root = root
        self.grid()
        self.local_ip = '127.0.0.1'
        self.serv_ports = [10888,20888,30888]
        self.init_components()


    #可视化组件设置函数
    def init_components(self):
        proj_name = Label(self,text="远程备份服务器")  #服务标签
        proj_name.grid(columnspan=2)


        serv_ip_label = Label(self,text="服务地址")
        serv_ip_label.grid(row=1)


        self.serv_ip = Combobox(self,values=self.get_ipaddr())  #将获取到的本机IP输出到选择列表中
        self.serv_ip.set(self.local_ip)
        self.serv_ip.grid(row=1,column=1)


        serv_port_label  = Label(self,text="服务端口")
        serv_port_label.grid(row=2)


        self.serv_port = Combobox(self,values=self.serv_ports)
        self.serv_port.set(self.serv_ports[0])
        self.serv_port.grid(row=2,column=1)


        self.start_serv_btn = Button(self,text="启动服务",command=self.start_serv)
        self.start_serv_btn.grid(row=3)


        self.start_exit_btn = Button(self,text="退出服务",command=self.root.destroy)
        self.start_exit_btn.grid(row=3,column=1)


    def get_ipaddr(self):  #通过socket模块获取本地IP信息及内容
        host_name = socket.gethostname()
        info = socket.gethostbyname_ex(host_name)
        info = info[2]  #gethostbyname_ex函数返回为('LAPTOP-5GCCVJ3P', [], ['10.10.10.2', '192.168.0.2', '192.168.184.1', '192.168.31.68']) ,将第二列复制给info
        info.append(self.local_ip)
        return info


    def start_serv(self):
        print(self.serv_ip.get(),self.serv_port.get())
        start(self.serv_ip.get(),int(self.serv_port.get()))
'''
功能:
    1、备份客户端的一个目录及其子目录中的所有文件
    2、与客户端交互流程


'''
if __name__ == '__main__':
    root = Tk()
    root.title("备份服务器")
    root.resizable(False,False)


    app = MyFrame(root)
    app.mainloop()

 客户端:

#客户端
from tkinter import *
from tkinter.ttk import *
import  socket
import struct
import os
import pickle
#获取文件信息函数
def get_file_info(path):
    if not path or not os.path.exists(path):
        return None
    files = os.walk(path)
    infos = []
    file_paths = []
    for p ,ds,fs in files:
        for f in fs:
            file_name = os.path.join(p,f)
            file_size = os.stat(file_name).st_size
            file_paths.append(file_name)
            file_name = file_name[len(path)+1:]
            infos.append((file_size,file_name))
    return infos,file_paths


#文件发送函数
def send_files_infos(my_sock,infos):
    fmt_str = 'Q'
    infos_bytes = pickle.dumps(infos)
    infos_bytes_len = len(infos_bytes)
    infos_len_pack = struct.pack(fmt_str,infos_bytes_len)
    my_sock.sendall(infos_len_pack)
    my_sock.sendall(infos_bytes)


def send_files(my_sock,file_path):
    f = open(file_path,'rb')
    try:
        while True:
            data = f.read(1024)
            if data:
                my_sock.sendall(data)
            else:
                break
    finally:
        f.close()


def get_bak_info(my_sock,size=7): #success字节
    info = my_sock.recv(size)
    print(info.decode('utf-8'))


def start(host,port,src):
    if not os.path.exists(src):
        print("备份目标不存在")
        return
    s = socket.socket()
    s.connect((host,port))
    path = src
    file_infos,file_paths = get_file_info(path)
    send_files_infos(s,file_infos)
    for fp in file_paths:
        send_files(s,fp)
        print(fp)
        get_bak_info(s)
    s.close()
#定义窗体类
class MyFrame(Frame):


    def __init__(self,root):
        super().__init__(root)
        self.root = root
        self.grid()
        self.remote_ip = '127.0.0.1'
        self.remote_ports = 10888
        self.remote_ip_var = StringVar()
        self.remote_ports_var = IntVar()
        self.bak_src_var = StringVar()
        self.init_components()


    #可视化组件设置函数
    def init_components(self):
        proj_name = Label(self,text="远程备份客户机")  #服务标签
        proj_name.grid(columnspan=2)


        serv_ip_label = Label(self,text="服务地址")
        serv_ip_label.grid(row=1)


        self.serv_ip = Entry(self,textvariable=self.remote_ip_var)  #将获取到的本机IP输出到选择列表中
        self.remote_ip_var.set(self.remote_ip)
        self.serv_ip.grid(row=1,column=1)


        serv_port_label  = Label(self,text="服务端口")
        serv_port_label.grid(row=2)


        self.serv_port = Entry(self,textvariable=self.remote_ports_var)
        self.remote_ports_var.set(self.remote_ports)
        self.serv_port.grid(row=2,column=1)


        src_label = Label(self,text='备份目标:')
        src_label.grid(row=3)


        self.bak_src = Entry(self, textvariable=self.bak_src_var)  # 将获取到的本机IP输出到选择列表中
        self.bak_src.grid(row=3, column=1)


        self.start_serv_btn = Button(self,text="开始备份",command=self.start_send)
        self.start_serv_btn.grid(row=4)


        self.start_exit_btn = Button(self,text="退出程序",command=self.root.destroy)
        self.start_exit_btn.grid(row=4,column=1)
    def start_send(self):
        print(self.remote_ip_var.get(),self.remote_ports_var.get())
        print('start....')
        print(self.bak_src_var.get())
        start(self.remote_ip_var.get(),int(self.remote_ports_var.get()),self.bak_src_var.get())


if __name__ == '__main__':
    root = Tk()
    root.title('远程备份客户机')
    root.resizable(False,False)
    app = MyFrame(root)
    app.mainloop()

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

security_dog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值