基于TCP实现文件传输(C#实现C端,Python实现S端)

4 篇文章 0 订阅

一、实验说明

  • 服务端(Server)是基于 python 实现
  • 客户端(Client)是基于 c# 实现
  • 实现功能:基于 TCP 方式的二进制文件传输,即,客户端发出获取图片/音乐等请求,服务器端响应请求,将图片/音乐等文件转换成字节流并向客户端发送,客户端接收字节流并转换成相应文件

二、服务端(Server)实现

  1. 实现流程

    ① 创建服务端的 socket 对象

    # 创建套接字对象
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    

    ② 绑定服务端的地址

    # 绑定IP,port
    tcp_server.bind(('', 5000)) # 本机
    

    ③ 设置监听器

    # 设置监听
    tcp_server.listen(5)
    

    ④ 等待客户端连接

    # 等待客户端的连接
    # accept()返回一个元组,元素一为客户端socket对象,元素二为客户端地址
    client_socket, addr = tcp_server.accept()
    

    ⑥ 接收客户端请求

    # 接收客户端的数据
    recv_msg = client_socket.recv(1024)
    # 对接收到的数据进行解码
    strData = recv_msg.decode("utf-8")
    

    ⑦ 返回处理结果到客户端

    # 对要返回的结果进行编码
    client_socket.send("ok".encode('utf-8'))
    
  2. 完整代码

    import socket
    
    
    # 将图片/音频文件转为字节存储
    def file_deal(message):
        mes = b''
        file = ''
        try:
            if message == 'pic':
                file = open("./" + str(num) + ".jpg", 'rb')
                mes = file.read()
            if message == 'music':
                file = open("./music.mp3", 'rb')
                mes = file.read()
        except:
            print("没有该文件!!!")
        else:
            file.close()
            # print(type(mes))
            return mes
    
    
    # 向客户端发送字节流
    def send_message(data):
        i = 0
        total = len(data)
        # 分批次发送
        while i < total:
            data_to_send = data[i:i+1024]
            client_socket.send(data_to_send)
            i += len(data_to_send)
    
    
    # 创建套接字对象
    tcp_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    # 绑定IP,port
    tcp_server.bind(('', 5000))
    # 设置监听
    tcp_server.listen(5)
    # 等待客户端的连接
    # accept()返回一个元组,元素一为客户端socket对象,元素二为客户端地址
    client_socket, addr = tcp_server.accept()
    num = 0  # 记录图片数
    while True:
        # 接收客户端的数据
        recv_msg = client_socket.recv(1024)
        # 对接收到的数据进行解码
        strData = recv_msg.decode("utf-8")
        if strData == 'aaa':
            num = num % 3
            data = file_deal("pic")
            # 发送文件长度和文件名
            client_socket.send('{}|{}'.format(len(data), str(num)+'.jpg').encode('utf-8'))
            reply = client_socket.recv(1024)
            # 确认接收
            if 'ok' == reply.decode('utf-8'):
                send_message(data)
                num += 1
    
        if strData == 'bbb':
            data = file_deal("music")
            # 发送文件长度和文件名
            client_socket.send('{}|{}'.format(len(data), str(num) + '.mp3').encode('utf-8'))
            reply = client_socket.recv(1024)
            # 确认接收
            if 'ok' == reply.decode('utf-8'):
                send_message(data)
                
        if strData == "break":
            # client_socket.send("连接已断开".encode('utf-8'))
            break
    
    # 关闭客户端服务的套接字
    client_socket.close()
    

三、客户端(Client)实现

  1. UI 设计

    ① 用 VS2017 新建一个 Windows 窗体应用(.NET Framework) 的项目

    ② 点击进入 From.cs[设计],可将界面设计如下:

  2. 核心代码实现

    ① 建立 TCP 连接,如何接收或者发送消息等,已在用C#实现网游客户端(采用TCP方式连接校园网服务器)核心代码实现部分已有过总结。

    ② 接收字节流

    private byte[] get_Datas()
    {
        //接收请求
        byte[] data = new byte[1024];
        //传递一个byte数组,用于接收数据。length表示接收了多少字节的数据
        int length = tcpClient.Receive(data);
        string message = Encoding.UTF8.GetString(data, 0, length);
        string[] array = message.Split('|');
        int total = int.Parse(array[0]);
        string file_name = array[1];
        List<byte> file = new List<byte>();
        if (total >= 0 && file_name != "")
        {
            tcpClient.Send(Encoding.UTF8.GetBytes("ok"));
            int get = 0;
            while (get < total)
            {
                length = tcpClient.Receive(data);
                for (int i = 0; i < length; i++)
                {
                    file.Add(data[i]);
                }
                get = get + length;
            }
        }
        //list转数组
        byte[] datas = file.ToArray();
        return datas;
    }
    

    ③ 使用 MCI Command String多媒体设备程序接口播放mp3

    a. 添加命名空间

    using System.Runtime.InteropServices;
    

    b. 定义全局变量

    public static uint SND_ASYNC = 0x0001;
    public static uint SND_FILENAME = 0x0002000;
    [DllImport("winmm.dll")]
    public static extern uint mciSendString(string lpstrCommand,string lpstrReturnString, uint uReturnLength, uint hWndCallback);
    

    c. 播放 music.mp3

    //音乐播放
    private void play()
    {
        mciSendString(@"close temp_alias", null, 0, 0);
        // 播放music.mp3
        mciSendString(@"open ""music.mp3"" alias temp_alias", null, 0, 0);
        // 循环播放
        mciSendString("play temp_alias repeat", null, 0, 0);
        // 设置音量
        mciSendString("setaudio movie volume to 1", null, 0, 0);
        listBox1.Items.Add("播放音乐!");
    }
    

    MCI 的具体说明请参考:媒体控制接口(MCI)的学习与使用

    ④ 将字节流转换成图片文件

    //将字节流转换为图片文件
    MemoryStream ms = new MemoryStream(datas);
    ms.Position = 0;
    Image img = Image.FromStream(ms);
    ms.Close();
    pictureBox1.Image = img;
    

    ⑤ 将字节流转换成mp3格式文件存放在本地

    //将字节流转换为mp3格式文件
    FileStream fs = new FileStream(@"music.mp3", FileMode.OpenOrCreate, FileAccess.Write);
    fs.Write(datas, 0, datas.Length);
    fs.Close();
    

四、效果展示

  1. 先启动服务器,然后在启动客户端

  2. 效果如下:

    图片和mp3已提前在服务端准备好了,目前只支持 *.jpg*.mp3格式。

五、参考🔗

六、完整源码

链接:https://pan.baidu.com/s/1hNs6OkciCCtkDT3d-Z5QfQ
提取码:zf31

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值