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

发布于:2023-01-13 ⋅ 阅读:(712) ⋅ 点赞:(0)

特别鸣谢(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;
}

本文含有隐藏内容,请 开通VIP 后查看

网站公告

今日签到

点亮在社区的每一天
去签到