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()

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 基于TCP的socket网络传输视频(C++, python) 可以实现C++ to C++、Python to python、C++ to Python的视频或图像传输。 ### 一. 概述 ### Socket的英文原义是“孔”或“插座”。作为BSD UNIX的进程通信机制,取后一种意思。通常也称作"套接字",用于描述IP地址和端口,是一个通信链的句柄,可以用来实现不同虚拟机或不同计算机之间的通信。在Internet上的主机一般运行了多个服务软件,同时提供几种服务。每种服务都打开一个Socket,并绑定到一个端口上,不同的端口对应于不同的服务。Socket正如其英文原意那样,像一个多孔插座。一台主机犹如布满各种插座的房间,每个插座有一个编号,有的插座提供220伏交流电, 有的提供110伏交流电,有的则提供有线电视节目。 客户软件将插头插到不同编号的插座,就可以得到不同的服务。网络上的两个程序通过一个双向的通信连接实现数据的交换,这个连接的一端称为一个socket。 而socket与socket之间的连接以及数据传输需要一种规则,也就是我们通常所说的网络传输协议,最常用的有TCPUDP,这两种协议的区别如下: 1.基于连接与无连接; 2.对系统资源的要求(TCP较多,UDP少); 3.UDP程序结构较简单; 4.流模式与数据报模式 ; 5.TCP保证数据正确性,UDP可能丢包,TCP保证数据顺序,UDP不保证。 接下来将以图片传输为例,用Python和C++实现服务端和客户端。这里不用语言得到的端口之间也可以互相连接。 ### 二. 运行要求 ### (1)OpenCV (2)Python 2.7 (3)C++的源文件要求windows环境 ### 三. 参考资料 ### -------- 该资源内项目源码是个人的毕设,代码都测试ok,都是运行成功后才上传资源,答辩评审平均分达到96分,放心下载使用! <项目介绍> 1、该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的,请放心下载使用! 2、本项目适合计算机相关专业(如计科、人工智能、通信工程、自动化、电子信息等)的在校学生、老师或者企业员工下载学习,也适合小白学习进阶,当然也可作为毕设项目、课程设计、作业、项目初期立项演示等。 3、如果基础还行,也可在此代码基础上进行修改,以实现其他功能,也可用于毕设、课设、作业等。 下载后请首先打开README.md文件(如有),仅供学习参考, 切勿用于商业用途。 --------

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

security_dog

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

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

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

打赏作者

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

抵扣说明:

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

余额充值