程设课终章:c++使用socket实现bmp图片的传输

2023-11-16

特别鸣谢(44条消息) C++ UDP发送接收文件(BMP)_我不在你不在的博客-CSDN博客

里面一些概念:

ip地址:电脑门牌号

端口号:做这件事的行动代号

协议:接收方和发送方都必须遵守的一种规则

socket是基于tcp/ip协议发送数据技术

这东西我也讲不太明白

详情原理见(44条消息) Socket通信原理探讨(C++为例)_Syymaily的博客-CSDN博客

总之我们要做的就是

写两个c艹程序

开两个窗口

接收方先运行等着接收

发送方运行发送指定文件的数据

接收方把数据下载到指定文件夹

(一次别发太多)

难点还是在搞明白每个花里胡哨的函数都是干嘛的

原作者debug感觉挺好用的,走到那步停了可以及时发现

还有就是原程序会丢包,我把发送文件sleep了一下,就能完整发过来了

整个过程除了调参就是一大大堆莫名其妙的bug,这里举几个大家可能遇到的

如果vs报错 fopen : This function or variable may be unsafe. Consider using fopen_s instead.....之类的 把fopen函数改成对应格式的fopen_s即可

如果你的vs把这里的文件地址标红了

我们依次点击项目--属性--高级下面的字符集

把字符集改成使用多字节字符集即可

 

如果你的vs把inet_addr标红了,或提示错误    C4996     inet_addr : Use inet_pton() or InetPton() instead or define #%¥……%%#%¥%……&%¥乱七八糟的

表示这是老函数,他更新之后不能用了,我们直接告诉他我就用,你说话不好使

点击项目--属性--c++--常规

把SDL检查改成否

还有就是端口号一定一定要相同

也许你也会调出一大坨不知名bug,不要急,直接百度或csdn错误提示一般都可以找到解决方法

 祝大家一次性成功

我的代码如下 全程vs

发送文件(client)客户端


#include <WinSock2.h>
#include <stdio.h>    
#include <stdlib.h>    
#include <string.h> 
#include<Windows.h>
#pragma comment(lib,"ws2_32.lib")
#define DEST_PORT 3000    
#define MAX_DATA 51200  //50kb    
#define DEST_IP_ADDRESS "127.0.0.1" //"192.168.1.113"//"10.42.0.1" //"192.168.1.19"//"169.254.9.36"    

#ifndef bool    
#define bool int    
#define true 1    
#define false 0    
#endif    

int main(int argc, char* argv[])
{
    WORD ver;
    WSADATA WSAData;
    ver = MAKEWORD(1, 1);
    if (WSAStartup(ver, &WSAData))
    {

        return 0;
    }
    if (LOBYTE(WSAData.wVersion) != 1 ||
        HIBYTE(WSAData.wVersion) != 1)
    {

        WSACleanup();
        return 0;
    }
    //与本地IP绑定
    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrS;
    addrS.sin_addr.s_addr = htonl(INADDR_ANY);
    addrS.sin_family = AF_INET;
    addrS.sin_port = htons(9999);
    bind(sock, (SOCKADDR*)&addrS, sizeof(SOCKADDR));
    //接收端的IP地址
    SOCKADDR_IN addrR;
    addrR.sin_addr.s_addr = inet_addr("127.0.0.1");
    addrR.sin_family = AF_INET;
    addrR.sin_port = htons(9999);
    int len = sizeof(SOCKADDR);
    //打开要发送文件
    BOOL    bSuccess;
    HANDLE  hFile;
    DWORD   dwFileSize, dwHighSize, dwBytesRead;
    hFile = CreateFile("D:\\Cpan\\Download\\eyes\\xw.bmp", GENERIC_READ, FILE_SHARE_READ, NULL,
        OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL);
    //"d:\\x.bmp"
    if (hFile == INVALID_HANDLE_VALUE)
    {
        printf("hfle");
        getchar();
        return 0;
    }
    dwFileSize = GetFileSize(hFile, &dwHighSize);//获得文件的大小
    if (dwHighSize)
    {
        CloseHandle(hFile);
        printf("hfle2");
        getchar();
        return 0;
    }
    //发送文件大小
    char strFileSize[20];
    _itoa_s(dwFileSize, strFileSize, 10);
    sendto(sock, strFileSize, 20, 0, (SOCKADDR*)&addrR, len);
    //读文件内容到readfile中
    BYTE* readfile;
    readfile = (BYTE*)malloc(dwFileSize);
    bSuccess = ReadFile(hFile, readfile, dwFileSize, &dwBytesRead, NULL);
    CloseHandle(hFile);
    if (!bSuccess || (dwBytesRead != dwFileSize))
    {
        free(readfile);
        printf("hfle3");
        getchar();
        return 0;
    }

    //eachSend表示每次发送字符的大小
    DWORD eachSend = 50 * 1024, retval, n, yu, i, j;
    BYTE  eachBuf[50 * 1024];
    n = dwFileSize / eachSend;  //共需要几次全额发送
    yu = dwFileSize % eachSend; //最后剩下的字符大小
    //先发送n次全额数据
    for (i = 0;i < n;i++)
    {
        Sleep(100);
        for (j = 0;j < eachSend;j++)
        {
            eachBuf[j] = readfile[i * eachSend + j];

        }
        retval = sendto(sock, (char*)eachBuf, eachSend, 0, (SOCKADDR*)&addrR, len);
        if (retval != eachSend)
        {
            printf("adsf");
            getchar();
            return 0;
        }
        memset(eachBuf, 0, 50 * 1024);
    }
    //再发送剩下的字符
    for (i = 0;i < yu;i++)
    {
        eachBuf[i] = readfile[n * eachSend + i];
    }
    retval = sendto(sock, (char*)eachBuf, yu, 0, (SOCKADDR*)&addrR, len);
    if (retval != yu)
    {

        return 0;
    }
    //中断winsocket库
    closesocket(sock);
    WSACleanup();
    printf("over");
    getchar();
    return 0;
}

接收端(server)服务器端


#include <WinSock2.h>
#include <stdio.h>    
#include <stdlib.h>    
#include <string.h> 
#include <time.h>

#pragma comment(lib,"ws2_32.lib")
#define SERV_PORT 3000    
#define MAX_DATA 51200  //50kb    
#define FILE_LENGTH 921654 //图片大小    
#ifndef bool    
#define bool int    
#define true 1    
#define false 0    
#endif    
int main()
{
    WORD ver;
    WSADATA WSAData;
    ver = MAKEWORD(1, 1);
    if (WSAStartup(ver, &WSAData))
    {
        printf("adsf2");
        getchar();
        return 0;
    }
    if (LOBYTE(WSAData.wVersion) != 1 ||
        HIBYTE(WSAData.wVersion) != 1)
    {
        printf("adsf3");
        WSACleanup();
        return 0;
    }
    //与本地IP绑定
    SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
    SOCKADDR_IN addrR;
    addrR.sin_addr.s_addr = htonl(INADDR_ANY);
    addrR.sin_family = AF_INET;
    addrR.sin_port = htons(9999);
    if (SOCKET_ERROR == bind(sock, (SOCKADDR*)&addrR, sizeof(SOCKADDR)))
    {
        printf("adsf4");
        WSACleanup();
        return 0;
    }
    //获取要接收文件的大小
    SOCKADDR_IN addrS;
    int len = sizeof(SOCKADDR);
    char strFileSize[20];
    recvfrom(sock, strFileSize, 20, 0, (SOCKADDR*)&addrS, &len);
    printf("%s", strFileSize);
    DWORD   dwFileSize;
    dwFileSize = atoi(strFileSize); //文件大小
    int a = clock();
    DWORD eachRecv = 50 * 1024, n, yu, i, j, retval;
    n = dwFileSize / eachRecv;
    yu = dwFileSize % eachRecv;
    char  eachBuf[50 * 1024];
    printf("adsf5111\n");

    BYTE* recvbuf = (BYTE*)malloc(dwFileSize);//初始化要存放数据的字符串
    printf("%d\n", n);
    for (i = 0;i < n;i++)
    {
        printf("adsf511133\n");
        retval = recvfrom(sock, eachBuf, eachRecv, 0, (SOCKADDR*)&addrS, &len);
        if (retval != eachRecv)
        {
            printf("adsf5");
            return 0;
        }
        for (j = 0;j < eachRecv;j++)
        {
            recvbuf[i * eachRecv + j] = (BYTE)eachBuf[j];
        }
        memset(eachBuf, 0, 50 * 1024);
    }


    printf("114514\n");
    retval = recvfrom(sock, eachBuf, yu, 0, (SOCKADDR*)&addrR, &len);
    if (retval != yu)
    {
        printf("adsfbbbb");
        return 0;
    }
    for (i = 0;i < yu;i++)
    {
        recvbuf[n * eachRecv + i] = (BYTE)eachBuf[i];
    }
    //写入文件
    FILE* fp;
    if (fopen_s(&fp, "D:\\Cpan\\Download\\eyes\\xwcon.bmp", "wb"))
        return false;
    fwrite(recvbuf, dwFileSize, 1, fp);
    fclose(fp);
    int b = clock() - a;
    printf("%d", b);
    //中断winsocket库
    closesocket(sock);
    WSACleanup();
    getchar();
    return 0;
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

程设课终章:c++使用socket实现bmp图片的传输 的相关文章

随机推荐

  • 关于考试管理系统的实现

    关于考试管理系统的实现 背景 随着各地人事机构招考需求不断增强 规模不断扩大 考务管理工作量不断加大 尤其是报名 缴费 考场编排和准考证制作这几项非常重要且有繁琐的工作 若是再依靠传统的线下人工方式进行 那将浪费大量的人力 时间和资源 针对
  • 单片机毕业设计 RFID智能门禁系统

    文章目录 1 简介 2 绪论 2 1 课题背景与目的 3 射频识别 3 1 射频识别技术 3 2 射频识别模块 3 2 1 RFID模块 3 2 2 RFID模块组成 4 系统设计 4 1 系统架构 4 1 1 硬件部分 4 1 2 软件部
  • 使用 git 提交到指定远程分支

    使用 git 提交到指定远程分支 git add git commit 或者使用 git commit m messges git pull origin 远程分支名 相当于指定分支的代码与当前分支的代码合并到了一起 git push or
  • 1分钟部署一个属于自己的网站,借助云开发静态网站部署属于自己的网站

    今天来教大家部署一个属于自己的第一个静态网站 因为这里借助小程序云开发的静态服务器资源 所以可以轻松的实现自己网站的部署 部署完以后可以在电脑浏览器 手机浏览器 微信公众号里面展示 老规矩 先看效果图 简单起见 我这里写一个最简单的html
  • IEEE 802.3以太网帧封装

    要求 1 要求画出界面 以太网帧的数据部分 源MAC地址和目的MAC地址均从界面输入 2 计算后的校验和字段和封装后的结果可以从界面上输出 3 生成多项式G X X8 X2 X1 1 或者生成多项式G X X32 X26 X23 X22 X
  • SpringBoot-基础篇复习(全)

    本文包含SpringBoot基础篇的所有知识点 大家一起来学习吧 开启一段新的旅程 加油吧 springboot是由Picotal团队提供的全新框架 用来简化spring的搭建和开发过程的配置 因为spring的配置比较繁琐 故引入了spr
  • 不吐不快:程序员到底有没有前途(一位前辈写的)

    早上到单位 看昨天晚上QQ群里的内容 有人在问做程序员怎么样 马上就有人跳出来告诉他程序员又苦 又累 要求又高 赚得也不比人多 而且30岁以后肯定失业那一套 对程序员的前途 自己有自己的想法 但这没什么好说的 而且每个人都有适合本人的路 也
  • ceph分布式存储-常见MON故障处理

    1 常见 MON 故障处理 Monitor 维护着 Ceph 集群的信息 如果 Monitor 无法正常提供服务 那整个 Ceph 集群就不可访问 一般来说 在实际运行中 Ceph Monitor的个数是 2n 1 n gt 0 个 在线上
  • [转]边界值法中的上点、内点和离点的定义

    上点 是指边界上的点 无论此时的域是开区间还是闭区间 开区间的话 上点就是在域外 闭区间的话 上点就是在域内 离点 是指离上点最近的点 这里就跟是闭区间还是开区间就有关系了 如果是开区间 那么离点就在域内 如果是闭区间 那么离点就在域外 内
  • TCP的keep-alive机制分析

    TCP中的keep alive机制 问题和解决思路 详细内容 缺陷分析 问题和解决思路 建立tcp连接后 双方互相发送信息 但是可能存在的情况是双方在处理数据 暂时并不会互相发送数据 那么这个时候如何判断双方连接是否依然正常 而没有意外断开
  • Python Using EXE

    OS This method has its disadvantage if we want to stop this process We need do it by ourselves except seize the terminal
  • 启动nacos时出现“nacos is starting with cluster”问题

    使用startup cmd命令启动是以集群方式启动nacos 可以看见命令行中有 nacos is starting with cluster 我们可以以单机方式启动nacos 执行以下命令 startup cmd m standalone
  • MySql导入导出数据库(含远程导入导出)

    一 导入导出本地数据库 导出 1 先运行cmd cd 到mysql安装目录中的bin文件夹 2 mysqldump u root p 数据库名 gt 导出文件名 sql 其他情况下 1 导出整个数据库 mysqldump u 用户名 p 数
  • 2023华为od机试 Java 实现【德州扑克】

    前言 本题使用Java解答 如果需要Python代码 请参考以下链接 链接 题目 我们可以选择五张牌 它们的范围是 每张牌的大小在2 10之间 或者字母J Q K A 牌花色为红桃 黑桃 梅花 方块四种花色之一 现在一共有6种牌型 牌型1
  • 最新的ARM-GCC下载安装指南

    GCC下载网址 https developer arm com tools and software open source software developer tools gnu toolchain gnu a downloads 我使
  • 搭建一个属于自己的个人网站怎样选择服务器

    不管是想搭建一个属于自己的个人网站 还是想开发一个企业项目上云 都必须拥有一台云服务器 云服务器是公有云的支柱之一 我用过很多大厂的云服务器 还记得读研期间我刚开始入门的时候 自己尝试搭建了一台云服务器建网站 后来在一个导师项目中刚好需要用
  • 双指针笔记

    双指针是在一次for循环中使用两个指针完成需要两个for循环的工作 其主要有两种方法 快慢双指针 从一端开始 设置两个速度不一样的指针进行遍历 public int removeElement int nums int val int fa
  • 关于C++中void*形参兼容问题,血的教训!

    关于C 中void 形参兼容问题 血的教训 C语言中void 作为形参的用法 C 中void 作为形参的用法 C语言中void 作为形参的用法 最近在实操一本算法书上的代码的时候 碰到了形如int comp void void 这样的形参列
  • 一种通用代码模型的构建与实现

    开发思路 总体开发思路 代码解析 需要考虑的问题是 目前已经实现了70 左右的功能 代码片段的内在结构 识别代码片段中所存在的对象元素 系统根据不同的对象元素的分类能快速执行相应的处理程序 将处理的结果进行传递 将处理过程进行缓存 保留代码
  • 程设课终章:c++使用socket实现bmp图片的传输

    特别鸣谢 44条消息 C UDP发送接收文件 BMP 我不在你不在的博客 CSDN博客 里面一些概念 ip地址 电脑门牌号 端口号 做这件事的行动代号 协议 接收方和发送方都必须遵守的一种规则 socket是基于tcp ip协议发送数据技术