Socket传输文件/传输图片(Windows)

2023-11-14

利用UDP socket 来传输文件与图片 流程图如下:
这里写图片描述

主要流程:
1.client端发送command请求,上传数据或者下载数据,选择文件路径;
2.server端应答,start代表开始传输,no代表拒绝;
3.fopen打开文件进行读取(fread)或者写入(fwrite),为了支持图片传输,以二进制方式打开文件;

Server端

//udp_server.h
#define BUFLEN 4096
#define SHUTDOWN 0
#define DOWNLOAD 1
#define UPLOAD 2
#define YES 3
#define NO 4
#define START 5
#define END 6
#define CONTENT 7
#define OK 8

struct packet
{
    int command;
    int buflen;  
    int seq;
    char buf[BUFLEN];
};

int socketfd;
int addr_len;
struct sockaddr_in server;
struct sockaddr_in client;
struct packet send_packet;
struct packet recv_packet;
int length;
char ip[20];
int port;
int command;
char file_path[256];
// udp_server.cpp

#include "stdafx.h"

#include <winsock2.h> 
#include "udp_file_server.h"

#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable:4996)


int main() {
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2, 2), &WSAData);
    /*-------------create UDP socket------------*/
    if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("create socket error\n");
        exit(1);
    }

    printf("Server: Please input the ip:\n");
    scanf("%s", ip);
    printf("Please input the port:\n");
    scanf("%d", &port);

    memset(&server,0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(ip);
    if (bind(socketfd, (struct sockaddr *)&server, sizeof(server)) == -1) {
        perror("bind error\n");
        exit(1);
    }

    addr_len = sizeof(client);
    while (1) {
        memset(&recv_packet,0, sizeof(recv_packet));
        length = recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&client, &addr_len);
        command = recv_packet.command;
        if (command == DOWNLOAD) {
            FILE *fd = fopen((recv_packet.buf), "rb");
            if (fd <0) {
                send_packet.command = NO;
                sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                printf(" no such file!\n");
                exit(1);
            }
            else {
                send_packet.command = YES;
                sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&client, &addr_len);
                if (recv_packet.command == START) {
                    int packet_seq = 0;
                    while ((length = fread(send_packet.buf, 1, BUFLEN,fd)) >0) {
                        send_packet.seq = packet_seq;
                        send_packet.command = CONTENT;
                        send_packet.buflen = length;
                        sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                        packet_seq++;
                        memset(&send_packet,0, sizeof(send_packet));
                        Sleep(10);
                    }
                    memset(&send_packet,0, sizeof(send_packet));
                    send_packet.command = END;
                    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
                }
            }
        }
        else if (command == UPLOAD) {
            printf("The client want to upload the file:  %s\n", recv_packet.buf);
            printf("Please choice start or no? \n");
            printf("5 :start,  4: no\n");
            scanf("%d", &send_packet.command);
            printf("Please input filepath \n");
            memset(file_path, 0, sizeof(file_path));
            scanf("%s", file_path);

            sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&client, sizeof(client));
            if (send_packet.command == START) {
                int packet_seq = 0;
                FILE *fd = fopen(file_path, "ab");
                if (NULL == fd)
                {
                    printf("fopen return NULL, error=%d/n", GetLastError());
                }
                if (fd < 0) {
                    perror("create file error\n");
                    exit(1);
                }
                memset(&recv_packet,0, sizeof(recv_packet));
                while ((length = recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&client, &addr_len)) >0) {
                    if (recv_packet.command == CONTENT) {
                        if ( recv_packet.seq == packet_seq) {
                            fwrite( recv_packet.buf,1,recv_packet.buflen,fd);
                            printf("传输数据中...  %s\n", recv_packet.buf);
                            memset(&recv_packet,0, sizeof(recv_packet));
                            packet_seq++;
                        }
                        else {
                            perror("The file no is not same.Some message is missed! error occured! \n");
                            break;
                        }
                    }
                    if (recv_packet.command == END) {
                        fclose(fd);
                        printf("transmission is successful!\n");
                        break;
                    }
                }
            }
            else if (send_packet.command == NO) {
                printf("Not to trans the file\n");
            }
            else {
                perror("error! wrong choice!\n");
                exit(1);
            }

        }
        else if (recv_packet.command == SHUTDOWN) {
            printf("Now the server is shutdown!\n");
            break;
        }
    }
    closesocket(socketfd);
    return 0;
}

Client端

//udp_client.h
#define BUFLEN 4096
#define SHUTDOWN 0
#define DOWNLOAD 1
#define UPLOAD 2
#define YES 3
#define NO 4
#define START 5
#define END 6
#define CONTENT 7
#define OK 8

struct packet
{
    int command;
    int buflen;  
    int seq;
    char buf[BUFLEN];
};

int socketfd;
int addr_len;
struct sockaddr_in server;
struct packet send_packet;
struct packet recv_packet;
int length;
char ip[20];
int port;
int command;
char file_path[256];

void ShowMenu();
void DownLoad();
void UpLoad();
void ShutDown();
// udp_client.cpp

#include "stdafx.h"
#include <winsock2.h> 
#include "udp_file_client.h"

#pragma comment(lib, "Ws2_32.lib")
#pragma warning(disable:4996)


int main() {
    WSADATA WSAData;
    WSAStartup(MAKEWORD(2, 2), &WSAData);
    //创建UDP socket
    if ((socketfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
        perror("socket error\n");
        exit(1);
    }

    printf("Client: Please input the ip:\n");
    scanf("%s", ip);
    printf("Please input the port:\n");
    scanf("%d", &port);

    memset(&server,0, sizeof(server));
    server.sin_family = AF_INET;
    server.sin_port = htons(port);
    server.sin_addr.s_addr = inet_addr(ip);
    addr_len = sizeof(server);

    while (1) {
        ShowMenu();
        scanf("%d", &command);
        if (command == SHUTDOWN) {
            ShutDown();
            break;
        }
        else if (command == DOWNLOAD) {
            DownLoad();
        }
        else if (command == UPLOAD) {
            UpLoad();
        }
        else {
            printf("Please make a right choice!\n");
        }
    }
    closesocket(socketfd);
    return 0;
}


void ShowMenu() {
    printf("=====================================\n");
    printf("         Please make a choice:       \n");
    printf("         0:  ||shutdown||            \n");
    printf("         1:  ||download||            \n");
    printf("         2:  || upload ||            \n");
    printf("=====================================\n");
}
void DownLoad() {
    memset(&recv_packet,0, sizeof(recv_packet));
    memset(&send_packet,0, sizeof(send_packet));
    memset(file_path,0, sizeof(file_path));
    printf("Please input the file_path:\n");
    scanf("%s", send_packet.buf);
    send_packet.command = DOWNLOAD;
    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
    memcpy(send_packet.buf, file_path, strlen(send_packet.buf));
    recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&server, &addr_len);
    if (recv_packet.command == YES) {
        printf("YES!\n");
        int command;
        printf("Press 5 to start  transmission!\n");
        scanf("%d", &command);
        printf("Please input the download path:\n");
        memset(file_path, 0, sizeof(file_path));
        scanf("%s", file_path);
        if (command == START) {
            send_packet.command = START;
            sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
            int packet_seq = 0;
            FILE *fd = fopen(file_path, "ab");
            if (fd < 0) {
                perror("create file error\n");
                exit(1);
            }
            memset(&recv_packet,0, sizeof(recv_packet));
            while ((length = recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&server, &addr_len)) >0) {
                if (recv_packet.command == CONTENT) {
                    if (packet_seq == recv_packet.seq) {
                        fwrite( recv_packet.buf,1, recv_packet.buflen,fd);
                        printf("传输数据中... %s\n",recv_packet.buf );
                        memset(&recv_packet,0, sizeof(recv_packet));
                        packet_seq++;
                    }
                    else {
                        perror("The file no is not same.Some message is missed! error occured! \n");
                        break;
                    }
                }
                if (recv_packet.command == END) {
                    fclose(fd);
                    printf("transmission is successful!\n");
                    break;
                }
            }
        }
    }
    else if (recv_packet.command == NO) {
        perror("NO such file on server!\n");
    }
    else {
        perror("recvbuf.command error\n");
        exit(1);
    }
}
void UpLoad() {
    memset(&recv_packet,0, sizeof(recv_packet));
    memset(&send_packet,0, sizeof(send_packet));
    memset(file_path,0, sizeof(file_path));
    printf("Please input the file name:\n");
    scanf("%s", send_packet.buf);
    send_packet.command = UPLOAD;
    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
    memcpy( file_path, send_packet.buf, strlen(send_packet.buf));

    FILE *fd = fopen(file_path, "rb");
    if (fd < 0) {
        perror("The file you want to trans is not exist!\n");
        exit(1);
    }
    recvfrom(socketfd, (char*)&recv_packet, sizeof(recv_packet), 0, (struct sockaddr *)&server, &addr_len);
    if (recv_packet.command == START) {
        int packet_seq = 0;
        memset(&send_packet, 0, sizeof(send_packet));
        while ((length = fread(send_packet.buf,1,BUFLEN,fd)) >0) {
            send_packet.seq = packet_seq;
            send_packet.command = CONTENT;
            send_packet.buflen = length;
            sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
            packet_seq++;
            memset(&send_packet,0, sizeof(send_packet));
            Sleep(10);
        }
        memset(&send_packet,0, sizeof(send_packet));
        send_packet.command = END;
        sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
    }
    else if (recv_packet.command == NO) {
        printf("not transmission\n");
    }
    else {
        perror("error! wrong choice!\n");
    }
}

void ShutDown() {
    printf("client is shutdown now!\n");
    memset(&send_packet,0, sizeof(send_packet));
    send_packet.command == SHUTDOWN;
    sendto(socketfd, (char*)&send_packet, sizeof(send_packet), 0, (struct sockaddr *)&server, sizeof(server));
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Socket传输文件/传输图片(Windows) 的相关文章

  • C# 中直接从 URL 获取图像尺寸

    我正在尝试使用以下代码直接从网络上获取图片的尺寸 string image http www hephaestusproject com csharp3 png byte imageData new WebClient DownloadDa
  • C# - Visual Studio 中的 System.OutOfMemoryException

    我遇到问题 当我右键单击 Visual Studio 中的主窗体并转到 视图设计器 时 出现错误 它说 引发了 System OutOfMemoryException 类型的异常 堆栈跟踪 at System Reflection Asse
  • 何时使用 C++ 私有继承而不是组合?

    你能给我一个具体的例子吗 什么时候使用私有继承优于组合 就我个人而言 我将使用组合而不是私有继承 但在某些情况下 使用私有继承可能是特定问题的最佳解决方案 正在阅读C faq http www parashift com c faq lit
  • 如何部署包含第三方 DLL 文件的 C# 应用程序?

    首先 我对部署了解不多 我希望我的问题有意义 我需要将 C 应用程序安装 部署到多个桌面 它需要一个第三方 DLL 文件 一个 C 库 lpsolve55 dll 对于那些感兴趣的人 它是一个免费的 MIP LP 求解器 请参阅 lpsol
  • 在 Windows 上使用 pycrypto 时如何修复“ImportError:无法从 Crypto.Cipher 导入名称 _AES”?

    我在 Crypto 的 Cipher 模块中有 AES Python27 Lib Crypto Cipher AES 当我尝试做的时候 from Crypto Cipher import AES 我收到以下错误 Traceback most
  • c 使用 lseek 以相反顺序复制文件

    我已经知道如何从一开始就将一个文件复制到另一个文件 但是我如何修改程序以按相反的顺序复制它 源文件应具有读取访问权限 目标文件应具有读写执行权限 我必须使用文件控制库 例如 FILE A File B should be ABCDEF FE
  • 使用默认行为将模型绑定到接口

    我正在尝试将控制器操作绑定到接口 但仍保持默认的绑定行为 public class CoolClass ISomeInterface public DoSomething get set ISomeInterface public clas
  • 应用新设置时如何防止 GraphicsDevice 被丢弃?

    我的游戏窗口允许手动调整大小 这意味着它可以像任何其他普通窗口一样通过拖动其边缘来调整大小 游戏还利用了RenderTarget2D rt2d 在主 Draw 方法中设置主渲染目标 GraphicsDevice SetRenderTarge
  • 多线程 - 比单线程慢

    当我使用多个线程而不是单线程运行程序时 它会变慢 不是应该更快吗 该程序应该遍历从起始目录开始的所有目录 并查找并打印所有名为 X 的文件 代码如下 while done pthread mutex lock lock if list is
  • 从 Golang 调用 C 函数

    我想在 Golang 中编写控制器逻辑并处理 json 和数据库 同时在 C 中使用我的数学处理模型 在我看来 调用 C 函数的开销必须尽可能低 就像设置寄存器 rcx rdx rsi rdi 一样 执行一些操作fastcall 并获取 r
  • += 运算符在 C++ 中是如何实现的?

    这是我一直在思考的一个问题 但从未找到任何资源来说明这个问题的答案 事实上它不仅是为了 也适用于它的兄弟姐妹 即 等等 当然不是 考虑这个例子 int a 5 a 4 this will make a 9 现在考虑等效表达式 a a 4 T
  • 原子的 C++ 内存屏障

    在这方面我是个新手 谁能提供以下内存屏障之间差异的简化解释 窗户MemoryBarrier 围栏 mm mfence 内联汇编asm volatile memory 内在的 ReadWriteBarrier 如果没有简单的解释 一些好文章或
  • 确定相关词的编程方式?

    使用网络服务或软件库 我希望能够识别与词根相关的单词 例如 座位 和 安全带 共享词根 座位 但 西雅图 不会被视为匹配 简单的字符串比较对于这类事情似乎是不可行的 除了定义我自己的字典之外 是否有任何库或 Web 服务不仅可以返回单词定义
  • 如何在 ASP.NET Core 项目中使用 MStest 测试 Ok() 结果

    我正在使用 MStest 来测试我的控制器 我想测试这个动作 HttpGet Name GetGroups public async Task
  • 动态菜单创建IoC

    我想知道是否有人知道我如何创建如何使用 AutoFac 之类的东西来让我动态地允许 dll 创建自己的表单和菜单项以在运行时调用它们 所以如果我有一个 员工 dll 新入门表格 证书表格 供应商 dll 供应商详细信息来自 产品形态 在我的
  • 如何使用“路径”查询 XDocument?

    我想查询一个XDocument给定路径的对象 例如 path to element I want 但我不知道如何继续 您可以使用以下方法System Xml XPath Extensions http msdn microsoft com
  • 在Python中设置Windows命令行终端标题

    我在 Windows 计算机上运行某个 Python 脚本的多个实例 每个实例都来自不同的目录并使用单独的 shell 窗口 不幸的是 Windows 为每个 shell 窗口提供了相同的名称
  • C# 模式匹配

    我对 C 有点陌生 我正在寻找一个字符串匹配模式来执行以下操作 我有一个像这样的字符串 该书将在 唐宁街 11 号接待处 并将由主要医疗保健人员参加 我需要创建一个 span 标签来使用 startIndex 和 length 突出显示一些
  • 包含从代码隐藏 (ASP.NET C#) 到 ASPX 中的图像概述的图像列表 [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 有没有办法在 C# 中仅通过文件名查找文件?

    我们现在使用绝对路径或相对路径在 C 应用程序中查找文件 如果文件位于当前工作目录下或 路径 之一下 有没有办法仅通过名称查找文件 使用绝对路径不好 使用相对路径也不够好 因为我们可能通过重命名或移动项目文件夹来更改项目结构 如果我们的代码

随机推荐

  • 《大白AI周报》精华内容整理汇总

    在人工智能学习中 大家或多或少都会关注一些公众号 但随着每天信息量的暴增 碎片化的内容让大家应接不暇 如何挖掘有价值的内容 如何快速查阅自己需要的内容 是一个头疼的问题 因此大白每周都会将人工智能领域 几十个公众号每周发布的精华内容汇总起来
  • 带你认识 MySQL 之 MySQL 体系结构

    序 最近一直在忙项目 各种加班加点 项目上线 渐渐的没有了学习的时间 这不 刚这几天才能抽出点时间 忙里偷闲 正在看一本数据库的书籍 相信很多小伙伴们也都看过 MySQL 技术内幕 InnoDB 存储引擎 这本书很详细的讲述了 MySQL
  • 水墨Shader解析

    Chinese Ink wash Painting II Shader 简介 本文尝试对Chinese Ink wash Painting II 来源 https www shadertoy com view DdSyDW 的代码部分进行解
  • 转载:数字图像去噪典型算法及matlab实现 (http://gaochaojs.blog.51cto.com/812546/243961)

    版权声明 原创作品 允许转载 转载时请务必以超链接形式标明文章 原始出处 作者信息和本声明 否则将追究法律责任 http gaochaojs blog 51cto com 812546 243961 数字图像去噪典型算法及matlab实现
  • Python爬虫(一):编写简单爬虫之新手入门

    最近学习了一下python的基础知识 大家一般对 爬虫 这个词 一听就比较熟悉 都知道是爬一些网站上的数据 然后做一些操作整理 得到人们想要的数据 但是怎么写一个爬虫程序代码呢 相信很多人是不会的 今天写一个针对新手入门想要学习爬虫的文章
  • Docker的inspect命令查看容器详细信息

    很久之前建的一个容器 今天发现找不到端口信息了 这都是小问题 执行docker inspect命令可以查看容器的详细信息 推荐 不用进入容器内部 命令格式为 docker inspect 想要查看信息的容器id或者容器名字 运行这个命令会返
  • 帮我写一个单连杆柔性机械臂的综述

    答 单连杆柔性机械臂是一种机械臂 它由多个连接器和柔性活动元件组成 它的主要优势在于其轻量级 可编程和低成本 具有良好的机械性能和可扩展性 它可用于模拟复杂的机械任务 例如机器人末端夹持和机械夹具控制 它可以实现高精度和高灵活性的操作 从而
  • buuctf [强网杯 2019]随便注 1

    buuctf web 强网杯 2019 随便注 1 刷题个人日记 小白一个 写给自己看 打开后是这样 从题目和内容来看就是一道sql注入题 输入 1 or 1 1 这个 用来注释掉后面的sql语句 显示所有数据 这个数据有什么用我也不知道
  • 解决:ERROR: Could not build wheels for horovod, which is required to install pyproject.toml-based

    解决 ERROR Could not build wheels for horovod which is required to install pyproject toml based projects 安装horovod的时候报错 由于
  • GetLastError返回值

    GetLastError返回的值通过在api函数中调用SetLastError或SetLastErrorEx设置 函数并无必要设置上一次错误信息 所以即使一次GetLastError调用返回的是零值 也不能担保函数已成功执行 只有在函数调用
  • KVM内核加载配置及技巧

    KVM 配置及技巧 加载KVM模块 1 检查加载状态 lsmod grep kvm若什么也没显示 说明还未加载 2 显示有哪些可加载模块 find lib modules name kvm 显示如下 lib modules 2 6 32 2
  • 宝塔面板linux在终端使用命令开启服务保持服务不关闭

    我们经常在宝塔面板终端开启服务 比如socket等服务时 如果关闭面板标签页或者关闭终端 服务也随之关闭了 要保持服务一直运行 就需要把终端进程放在linux后台执行 方法如下 1 先Ctrl z 将命令保持挂载 并且能够继续在终端输入其他
  • C语言经典100例题(42)--学习使用auto定义变量的用法

    目录 题目 问题分析 代码 运行结果 题目 学习使用auto定义变量的用法 问题分析 auto存储类型只对属于块的变量有效 auto变量具有自动存储期限 块作用域 并且无连接 auto存储类型几乎从来不用明确地指明 因为对于在块内部声明的变
  • 关于排水管道沉积模拟建模的想法

    首先管道沉积是一个较为复杂的过程 对其分析主要考虑了无机盐所造成的影响 在立项书中 已经给出了各种元素的占比 据此可推理出对沉积起着主导作用的化学反应 在排水管中原本的污水 所以考虑的重点方向就是在特定温度 特定流速下 无机盐的沉积量随时间
  • Shell脚本中字符串截取功能

    在Shell脚本编写中 有几个地方都是要用到字符串截取的功能 那将这块的内容进行下记录 1 字符串变量的截取操作 对字符串变量的截取操作一般都是通过 操作符 的方式进行 1 从指定位置index截取固定长度 格式 string start
  • Oracle中的锁

    Oracle数据库支持多个用户同时与数据库进行交互 每个用户都可以同时运行自己的事务 从而也需要对并发访问进行控制 Oracle也是用 锁 的机制来防止各个事务之间的相互影响 对并发访问进行控制的 保证数据的一致性和完整性 当一个事务或操作
  • 【工具】python代码编辑器--PyCharm下载安装和介绍

    PyCharm是一种Python IDE 集成开发环境 由JetBrains打造 它带有一整套可以帮助用户在使用Python语言开发时提高其效率的工具 比如调试 语法高亮 项目管理 代码跳转 智能提示 自动完成 单元测试 版本控制等 此外
  • 【华为OD】

    华为OD试题注意事项 使用合适的编程语言 在华为OD机试中多数情况下使用C 或Java 按照题目要求进行编码 仔细阅读题目描述并理解要求 在编码前可以进行伪代码编写或画流程图有助于理解和排除逻辑错误 注意代码的规范性 注重代码的可读性和可维
  • Python有趣小程序代码

    1 打印心形 print n join join Love x y 4 if x 0 05 2 y 0 1 2 1 3 x 0 05 2 y 0 1 3 lt 0 else for x in range 30 30 for y in ran
  • Socket传输文件/传输图片(Windows)

    利用UDP socket 来传输文件与图片 流程图如下 主要流程 1 client端发送command请求 上传数据或者下载数据 选择文件路径 2 server端应答 start代表开始传输 no代表拒绝 3 fopen打开文件进行读取 f