windows下C语言学习--在两台电脑之间传文件

客户端client.c

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<WinSock2.h>//头文件
#include<string.h>
#include <sys/stat.h>
#pragma comment(lib,"Ws2_32.lib")//网络库

#define PORT 8180
#define CON_IP "192.168.0.1"
// #define CON_IP "192.168.0.100"

#define OPEN_FILE "C:\\Desktop\\test"
#define BUFFLEN 4096
int main()
{
    WORD wdversion = MAKEWORD(2, 2);//关于内存 需要的版本  wdversion转换为二进制高字节装副版本号 低字节装主版本号
    WSADATA wdsockmsg;     //可以用指针 要申请堆空间 并且释放 在这里栈空间已经足够
    int nres = WSAStartup(wdversion, &wdsockmsg);//打开网络库
    if (nres != 0)
    {
        switch (nres)
        {
        case WSASYSNOTREADY:
            printf("restart computer");
            break;
        case WSAVERNOTSUPPORTED:
            printf("update socket library");
            break;
        case WSAEINPROGRESS:
            printf("restart");
            break;
        case WSAEPROCLIM:
            printf("close no need program");
            break;  //错误代码的解释
        }
        return 0;
    }


    if (HIBYTE(wdsockmsg.wVersion) != 2 || LOBYTE(wdsockmsg.wVersion) != 2)//校验版本
    {
        //版本不对
        WSACleanup();//清理关闭网络库
        return 0;
    }

    SOCKET socketclient = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //操作接口 调用协议通信 第三个参数可以为0默认参数值 此处默认为tcp
    //第一个参数ip地址类型 第二个套接字类型 第三个传输协议

    if (socketclient == INVALID_SOCKET)
    {
        printf("socketclient error = %d !\n",WSAGetLastError);//连接失败出错了 找出错误码进行改正
        WSACleanup();   //清理网络库
        system("pause");
        return 0;
    }

    struct sockaddr_in client;
    client.sin_family = AF_INET;//ipv4
    client.sin_port = htons(PORT);
    client.sin_addr.S_un.S_addr = inet_addr(CON_IP);

    int con = connect(socketclient, (const struct sockaddr*)&client, sizeof(client));
    printf("connect server = %d !\n",con);
    if (con == SOCKET_ERROR)
    {
        printf("connecting server error = %d !\n",WSAGetLastError);//连接失败出错了 找出错误码进行改正
        closesocket(socketclient); //关闭网络连接(服务端)
        WSACleanup();//关闭网络库
        system("pause");
        return 0;
    }


    char recvbuf[BUFFLEN] = { 0 };
    int res = recv(socketclient, recvbuf, 1024, 0);//参数一指接受数据的来源socket,参数二指接受到的字符数组 最大长度一次一般为1500,参数三指需要接受的字符数组的长度,参数四设为0;
    if (res == 0)
    {
        printf("connecting client outline!\n");
    }
    else if (res == SOCKET_ERROR)
    {
        printf("SOCKET_ERROR = %d !\n",WSAGetLastError);//出错了 找出错误码进行改正
        system("pause");
        return 0;
    }
    else
    {
        printf("recv from server [%s] len[%d]\n", recvbuf, res);
    }

    struct stat file_stat;
    int ret = 0;
    int fd = -1;
    long int filesize=0;
    fd = open(OPEN_FILE, 0); // 只读打开文件
    ret = fstat(fd, &file_stat);
    if (ret == -1)
    {
        printf("Get file %s stat failed!\n", OPEN_FILE);
        closesocket(socketclient); //关闭网络连接(服务端)
        WSACleanup();//关闭网络库

        return -1;
    }
    filesize=(long int)file_stat.st_size;
    printf("file size is %ld!\n", filesize);
    close(fd);

    FILE *fp = NULL;
    char sendbuf[BUFFLEN] = { 0 };
    fp = fopen(OPEN_FILE,"rb");
    if(fp == NULL)
    {
        printf("file %s miss!\n", OPEN_FILE);
        closesocket(socketclient); //关闭网络连接(服务端)
        WSACleanup();//关闭网络库
        return 0;
    }

    long int sendbyte=0;
    long int nowsendbyte=0;
    while((sendbyte=fread(sendbuf, 1, BUFFLEN, fp)) != 0)
    {
        nowsendbyte=ftell(fp);
        // printf("filesize=%ld,nowsendbyte=%d, progress=%.1f%% \n",filesize,nowsendbyte,((nowsendbyte*1.0)/(filesize*1.0)*100) );
        printf("%.1f%% \n",((nowsendbyte*1.0)/(filesize*1.0)*100) );
        // printf("sendbyte %ld \n",sendbyte );
        send(socketclient, sendbuf, sendbyte, 0);//sendbyte读到多少发多少
        memset(sendbuf,0,sizeof(sendbuf));
    }
    fclose(fp);
    closesocket(socketclient); //关闭网络连接(服务端)
    WSACleanup();//关闭网络库
    system("pause");

    return 0;
}


服务端server.c

#define _CRT_SECURE_NO_WARNINGS
#define _WINSOCK_DEPRECATED_NO_WARNINGS
#include <windows.h>
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include <sys/types.h>
#include <unistd.h>//头文件

#include<WinSock2.h>//头文件
#pragma comment(lib,"Ws2_32.lib")//网络库

#define PORT 8180
#define LIN_IP "0.0.0.0"
#define OPEN_FILE "C:\\Desktop\\test"
#define BUFFLEN 4096


int main()
{
    WORD wdversion = MAKEWORD(2, 2);//关于内存 需要的版本  wdversion转换为二进制高字节装副版本号 低字节装主版本号
    WSADATA wdsockmsg;     //可以用指针 要申请堆空间 并且释放 在这里栈空间已经足够
    int nres = WSAStartup(wdversion, &wdsockmsg);//打开网络库

    if (nres != 0)
    {
        switch (nres)
        {
        case WSASYSNOTREADY:
            printf("restart computer");
            break;
        case WSAVERNOTSUPPORTED:
            printf("update socket library");
            break;
        case WSAEINPROGRESS:
            printf("restart");
            break;
        case WSAEPROCLIM:
            printf("close no need program");
            break;  //错误代码的解释
        }
        return 0;
    }

    if (HIBYTE(wdsockmsg.wVersion) != 2 || LOBYTE(wdsockmsg.wVersion) != 2)//校验版本
    {
        //版本不对
        WSACleanup();//清理关闭网络库
        return 0;
    }

    SOCKET socketsever = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); //操作接口 调用协议通信 第三个参数可以为0默认参数值 此处默认为tcp
    //第一个参数ip地址类型 第二个套接字类型 第三个传输协议

    if (socketsever == INVALID_SOCKET)
    {
        int error = WSAGetLastError();  //错误码
        WSACleanup();   //清理网络库
        return 0;
    }

    struct sockaddr_in sever;
    sever.sin_family = AF_INET;//ipv4
    sever.sin_port = htons(PORT);
    sever.sin_addr.S_un.S_addr = inet_addr(LIN_IP);

    bind(socketsever, (const struct sockaddr*)&sever, sizeof(sever));//服务器端要用 bind() 函数将套接字与特定的 IP 地址和端口绑定起来
    /*bind第一个参数是socket变量 第二个参数为结构体变量addr里面有端口号 ip地址 第三个变量为addr变量的大小*//*(返回值正确为0 错误返回错误码)*/

    listen(socketsever, SOMAXCONN);//开始监听

    if (listen(socketsever, SOMAXCONN) == SOCKET_ERROR)
    {
        int error2 = WSAGetLastError();//获得错误码
        closesocket(socketsever); //关闭网络连接
        WSACleanup();//关闭网络库
        return 0;
    }
    while(1)
    {
        printf("waiting for connect!\n");
        struct sockaddr_in client;//创建客户端信息 系统自动填写
        int len = sizeof(client);
        SOCKET socketclient = accept(socketsever, (struct sockaddr*)&client, &len); //返回一个socket 客户端的socket 不想知道客户端的socket时把第二个人参数置为NULL
        if (socketsever == INVALID_SOCKET)//invalid_socket 表示socket创建无效的返回值
        {
            printf("client connect error!\n");
            int error3 = WSAGetLastError();  //错误码
            closesocket(socketsever); //关闭网络连接
            WSACleanup();//关闭网络库
            return 0;
        }


        printf("client connect success!\n");

        char srvsendbuf[BUFFLEN]= {0};
        sprintf(srvsendbuf,"I am server! you are connecting!");
        int srvsendres = send(socketclient, srvsendbuf, strlen(srvsendbuf), 0);//创建发送函数 参数与接受类似 若无错误返回发送的总字节数
        if (srvsendres == SOCKET_ERROR)
        {
            int error5 = WSAGetLastError();
            printf("error code=%d.\n",error5);
            return 0;
        }

        FILE *fp = NULL;
        fp=fopen(OPEN_FILE,"wb+");
        if(fp == NULL)
        {
            printf("file %s error!\n", OPEN_FILE);
            closesocket(socketclient); //关闭网络连接(服务端)
            closesocket(socketsever); //关闭网络连接(服务端)
            WSACleanup();//关闭网络库
            return 0;
        }
        char srvrecvbuf[BUFFLEN] = { 0 };
        int recvbyte = 0;
        while((recvbyte = recv(socketclient, srvrecvbuf, BUFFLEN, 0)) > 0 )
        {
            // printf("recvbyte:%d\n", recvbyte);
            fwrite(&srvrecvbuf, 1, recvbyte, fp);//是以二进位方式写入文件,recvbyte收到多少写多少
            // fwrite(数据,数据类型大小(字节数),写入数据的最大数量,文件指针);
            memset(srvrecvbuf,0,sizeof(srvrecvbuf));
        }
        printf("file size %ld \n",ftell(fp) );
        fclose(fp);
        closesocket(socketclient);//关闭网络连接(客户端)
    }

    closesocket(socketsever); //关闭网络连接(服务端)
    WSACleanup();//关闭网络库
    system("pause");

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值