标题:小鱼儿----文件传送工具(支持打同时接收和传送)c语言版 0.1
只看楼主
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
结帖率:95.74%
 问题点数:0 回复次数:11 
小鱼儿----文件传送工具(支持打同时接收和传送)c语言版 0.1
这个版本用的几乎都是用c 能不用API 就不API。。
可以同时支持接收文件和传送文件。

但不支持断点传送。自己还没有学。。

传送的时候没有显示。在文件传送完会提示的。。
程序代码:
头文件:

#ifndef FILE_SEND_TOOL_H
#define FILE_SEND_TOOL_H

#include <WINDOWS.H>
#include <stdio.h>
#include <WINSOCK.H>
#include <IO.H>

#pragma comment(lib,"ws2_32")


#define CHUNK_SIZE (1024*64)
#define BUF_LEN 1024
#define BIND_PORT 6665 //本身绑定端口
#define RECV_PORT 6667 //接受端口

#define CHEKPASS  0 //验证密码 这个不想在c的控制台实现。
#define RECVFile  1 //接受文件


#define SURE_GETFILE 3 //接受文件做好准备

typedef struct tagFileInfo
{
    int FileSize;
    char FileName[MAX_PATH];
    BOOL IsFolder;

}FileInfo;

typedef struct tagCOMMENT
{
    int ID;
    char lparam[BUF_LEN];
}COMMENT;

SOCKET Server;
SOCKET Client;
SOCKADDR_IN ServerAddr;

int SureGetFile = 0; //可以发送文件信号

char Pass[12]; //保存连接的时候密码
//char SaveName[MAX_PATH]; //接收文件的时候保存的文件名



DWORD WINAPI SendProc(LPVOID lparam); //发送文件线程
DWORD WINAPI RunProc(LPVOID lparam);

void RecvFile(char *buf,SOCKET Client1);
void SendFile(char *filename,char *ip);

void UserMenu();
//保存用户信息用于保存在硬盘上
//用于以后扩展的结构
typedef struct tagUSER
{
    char IP[32+1];
    char UserName[MAX_PATH];
}USER;

#endif
下面是cpp
程序代码:
#include "FileSendTool.h"

int main()
{
    WSADATA wsa;
    WSAStartup(MAKEWORD(2,2),&wsa);

    Server = socket(AF_INET,SOCK_STREAM,0);
    if(Server == INVALID_SOCKET)
    {
        puts("创建套接字失败");
        return 0;
    }

    ServerAddr.sin_addr.S_un.S_addr =htonl(INADDR_ANY);
    ServerAddr.sin_family = AF_INET;
    ServerAddr.sin_port = htons(BIND_PORT);

    if(bind(Server,(SOCKADDR*)&ServerAddr,sizeof(ServerAddr)) == SOCKET_ERROR)
    {
        puts("端口绑定失败");
        return 0;
    }

    if(listen(Server,5) == SOCKET_ERROR)
    {
        puts("listen 失败");
        return 0;
    }
   
    char buf[BUF_LEN];
    memset(buf,0,sizeof(buf));
    CreateThread(0,0,SendProc,0,0,0);
    while(1)
    {
        int len = sizeof(ServerAddr);
        Client = accept(Server,(SOCKADDR*)&ServerAddr,&len);
        if(Client == INVALID_SOCKET)
        {
            continue;
        }
        CreateThread(0,0,RunProc,(LPVOID)Client,0,0);
    }
   
   
}



DWORD WINAPI RunProc(LPVOID lparam)
{
    int flag = 1;
    SOCKET Client = (SOCKET)lparam;
    while(flag)
    {
        COMMENT cmd;
        memset(&cmd,0,sizeof(cmd));
        int ret = recv(Client,(char*)&cmd,sizeof(cmd),0);
        if(SOCKET_ERROR == ret)
        {
            puts("网络出现错误");
        }
        switch(cmd.ID)
        {
        case CHEKPASS:
            break;
        case RECVFile:
            RecvFile(cmd.lparam,Client);
            flag = 0;
            break;
        default:
            break;
        }
    }
    return 0;
}

void RecvFile(char *buf,SOCKET Client1)
{
    FileInfo fi;
    int nLeft = 0;
    int nRead = 0;
    char date[CHUNK_SIZE];
    memset(date,0,sizeof(date));
   
    SOCKET Rfs;
    SOCKADDR_IN addr;
    Rfs = socket(AF_INET,SOCK_STREAM,0);
    addr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    addr.sin_family = AF_INET;
    addr.sin_port = htons(RECV_PORT);
    if(bind(Rfs,(SOCKADDR*)&addr,sizeof(addr))==SOCKET_ERROR)
    {
        puts("绑定文件接受端口失败");
        closesocket(Rfs);
        return;
    }

    if(listen(Rfs,5) == SOCKET_ERROR)
    {
        puts("listen 接受文件失败");
        closesocket(Rfs);
        return;
    }
    COMMENT cmd;
    cmd.ID = SURE_GETFILE;

    if(send(Client1,(char*)&cmd,sizeof(cmd),0) == SOCKET_ERROR) //发送确定接受文件消息
    {
        puts("对方已经退出");
        closesocket(Rfs);
        return;
    }
   
    int len = sizeof(addr);
    SOCKET Client = accept(Rfs,(SOCKADDR*)&addr,&len);
    if(Client == INVALID_SOCKET)
    {
        puts("accept 接受文件失败");
        closesocket(Client);
        closesocket(Rfs);
        return;
    }

    memcpy(&fi,buf,sizeof(FileInfo));

    int nCount = fi.FileSize/CHUNK_SIZE;
    if(nCount == 0 || nCount*CHUNK_SIZE!=fi.FileSize)
    {
        nCount++;
    }

    char name[MAX_PATH];
    memset(name,0,sizeof(name));
    strcpy(name,strrchr(fi.FileName,'\\')+1); //获取文件名而不是full name 保存在当前目录 因为
    //我这个程序设计几个线程 别的线程也有关于控制台的读写 我就不好要用户写入要保存的位置。

    //puts("文件名字");
    //puts(name);
    FILE *fw = fopen(name,"wb");

    for(int i =0; i<nCount; i++)
    {
        if(i+1 == nCount)
        {
            nLeft = fi.FileSize - (nCount-1)*CHUNK_SIZE;
        }
        else
        {
            nLeft = CHUNK_SIZE;
        }
        while(nLeft>0)
        {
            int ret = recv(Client,&date[nRead],nLeft,0);
            if(ret == SOCKET_ERROR ||ret ==0)
            {
                puts("网络出现问题");
                closesocket(Client);
                closesocket(Rfs);
                return;
            }
            //printf("接受数据%d\n",ret);
            nRead+=ret;
            nLeft-=ret;
        }
        fwrite(date,sizeof(char),CHUNK_SIZE,fw);
        nRead = 0;

    }
    fclose(fw);
    closesocket(Rfs);
    closesocket(Client);
    //puts("接受完成");
    MessageBox(0,"接受完成",0,0);
}

void SendFile(char *filename,char *ip)
{
    SOCKET SendS;
    SOCKADDR_IN SerVerAddr;
    SerVerAddr.sin_addr.S_un.S_addr = inet_addr(ip);
    SerVerAddr.sin_family = AF_INET;
    SerVerAddr.sin_port = htons(RECV_PORT);

    SendS = socket(AF_INET,SOCK_STREAM,0);
    if(INVALID_SOCKET == SendS)
    {
        puts("创建传送套接字失败");
        return;
    }
    if(connect(SendS,(SOCKADDR*)&SerVerAddr,sizeof(SerVerAddr)) == SOCKET_ERROR)
    {
        puts("连接错误");
        closesocket(SendS);
    }
   
    //puts("接入文件传送端口");
    FileInfo fi;
    int nRead = 0;
    int nLeft = 0;
    char date[CHUNK_SIZE];
    memset(date,0,sizeof(date));

    strcpy(fi.FileName,filename);
   
    FILE *fp = fopen(fi.FileName,"rb");

    if(NULL == fp)
    {
        puts("打开文件失败");
        closesocket(SendS);
        return;
    }
   
    fseek(fp,0,SEEK_END);
    fi.FileSize = ftell(fp);
    rewind(fp);
   
    //printf("文件大小 %d",fi.FileSize);


    int nCount = fi.FileSize/CHUNK_SIZE;

    if(nCount == 0 || nCount*CHUNK_SIZE != fi.FileSize)
    {
        nCount++;
    }
    //printf("nCount is %d\n",nCount);
    for(int i =0; i < nCount ; i++)
    {
        if(i+1 ==nCount)
        {
            nLeft = fi.FileSize - (nCount-1)*CHUNK_SIZE;
        }
        else
        {
            nLeft = CHUNK_SIZE;
        }

        fread(date,sizeof(char),nLeft,fp);

        while(nLeft >0)
        {
           
            int ret = send(SendS,&date[nRead],nLeft,0);
            //printf("lk %d",GetLastError());
            if(SOCKET_ERROR == ret)
            {
                puts("文件传送出现错误");
                closesocket(SendS);
                int len = GetLastError();
                printf("错误代码 %d",len);
                return;
            }
            Sleep(10);

            //printf("传送数据 %d",nRead);

           
            nRead+=ret;
            nLeft-=ret;
        }
        nRead =0;
    }
    //puts("传送完成");
    //Sleep(10);
    MessageBox(0,"传送完成",0,0);
    fclose(fp);
    closesocket(SendS);
}

void UserMenu()
{
    char ip[32+1];
    char filename[MAX_PATH];

    memset(ip,0,sizeof(ip));
    memset(filename,0,sizeof(filename));
    FILE *fp;

    while(1)
    {
        system("cls");
        puts("\t\t 欢迎使用小鱼儿文件传送工具");
        puts("\t你需要传送数据吗:(1 是 0 否 2代表推出程序)");
       
        int ret = -1;
        scanf("%d",&ret);
        fflush(stdin);
       
        switch(ret)
        {
        case 1:
            puts("请输入对方的IP地址");
            gets(ip);
            fflush(stdin);
            puts("请输入文件名字");
            gets(filename);
            fflush(stdin);
            if(strlen(ip) == 0||strlen(filename) == 0)
            {
                puts("请输入正确的数据");
                continue;
            }
            SOCKET Client;
            SOCKADDR_IN Addr;
           
            Client = socket(AF_INET,SOCK_STREAM,0); //创建套接字与对方创建发送文件
            if(Client == INVALID_SOCKET)
            {
                puts("UserMenu 创建套接字失败");
                exit(3);
                return;
            }

            Addr.sin_addr.S_un.S_addr = inet_addr(ip);
            Addr.sin_family = AF_INET;
            Addr.sin_port = htons(BIND_PORT);

            COMMENT cmd;
            cmd.ID = RECVFile;
            FileInfo fi;
            strcpy(fi.FileName,filename);
            fp = fopen(filename,"rb");
            if(NULL == fp)
            {
                puts("打开文件失败");
                closesocket(Client);
                continue;
            }

            //获得文件大小
            fseek(fp,0,SEEK_END);
            fi.FileSize = ftell(fp);
            fclose(fp);

           
            if(connect(Client,(SOCKADDR*)&Addr,sizeof(Addr))== SOCKET_ERROR)
            {
                puts("连接出现错误");
                closesocket(Client);
                continue;
            }
            memcpy(cmd.lparam,&fi,sizeof(fi));

            //发送要传送文件信息
            if(send(Client,(char*)&cmd,sizeof(cmd),0) == SOCKET_ERROR)
            {
                puts("发送文件失败");
                closesocket(Client);
                continue;
            }
            memset(&cmd,0,sizeof(cmd));

            //等被接收放发送信息来确认
            if(recv(Client,(char*)&cmd,sizeof(cmd),0) == SOCKET_ERROR)
            {
                puts("接受文件失败");
                closesocket(Client);
                continue;
            }

            SendFile(filename,ip);
            break;
       
        case 2:
            closesocket(Server);
            WSACleanup();
            exit(3);
            break;
        default:
            system("cls");
            break;
    }
    }
}

DWORD WINAPI SendProc(LPVOID lparam)
{
    while(1)
    {
        UserMenu();
    }
}

附件:
小鱼儿文件传送工具.zip (24.54 KB)





[ 本帖最后由 小鱼儿c 于 2012-3-7 21:56 编辑 ]
搜索更多相关主题的帖子: c语言 工具 小鱼儿 断点 
2012-03-07 21:50
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
得分:0 
貌似在金山下报毒。。
我可没有写任何危害计算机的代码。
上面代码可以看出来。。

不能在一台机子上测试,因为 程序是服务端又是客服端。
所以不能测试。
要在2台电脑上测试。。

这个版本我测试了,500M 的 同时传送没有问题。。
只测试一个局域网的。
不在一个局域网 都是公网IP 没有测试。。不知道怎么样。
大家感兴趣的话,代码可以任意修改。。
想hellovfp了。。


用心做一件事情就这么简单
2012-03-07 21:54
smallmoon521
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:517
专家分:1373
注 册:2008-4-21
得分:0 
板凳? 赞一个

为游戏狂~~!!    大家努力编哈!
2012-03-07 21:57
hellovfp
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:禁止访问
威 望:30
帖 子:2976
专家分:7697
注 册:2009-7-21
得分:0 
头文件注释还不错。有在虚似机里测试过服务器客服端么?
数据库这学期开始学了么?

我们都在路上。。。。。
2012-03-08 13:23
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
得分:0 
以下是引用hellovfp在2012-3-8 13:23:35的发言:

头文件注释还不错。有在虚似机里测试过服务器客服端么?
数据库这学期开始学了么?
呵呵,回来了啊。。

以前搞过绿色的虚拟机,但没有把那个设置好,不能实现外面机子给虚拟机的机子传送数据。
然后那个删除了。。

开了。才学几节。。。
只是学到稍微的一些模式吧。。。

用心做一件事情就这么简单
2012-03-08 16:12
smallmoon521
Rank: 9Rank: 9Rank: 9
等 级:蜘蛛侠
威 望:4
帖 子:517
专家分:1373
注 册:2008-4-21
得分:0 
数据库要好好学,早晚要学的,上学不学,工作了也要用的
出来混的,早晚要还的,跑不了。。。不了。。。了。。。

为游戏狂~~!!    大家努力编哈!
2012-03-08 16:59
小鱼儿c
Rank: 9Rank: 9Rank: 9
等 级:贵宾
威 望:14
帖 子:852
专家分:1317
注 册:2011-4-1
得分:0 
以下是引用smallmoon521在2012-3-8 16:59:37的发言:

数据库要好好学,早晚要学的,上学不学,工作了也要用的
出来混的,早晚要还的,跑不了。。。不了。。。了。。。
嗯,谢谢sm

用心做一件事情就这么简单
2012-03-08 17:00
cosdos
Rank: 9Rank: 9Rank: 9
来 自:ShangHai
等 级:蜘蛛侠
威 望:6
帖 子:2109
专家分:1385
注 册:2007-6-19
得分:0 
顶一下

—>〉Sun〈<—
2012-03-08 19:12
hellovfp
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:禁止访问
威 望:30
帖 子:2976
专家分:7697
注 册:2009-7-21
得分:0 
回复 5楼 小鱼儿c
找个安装版的吧。。。绿色版的好象都有点问题。
偶这里有收藏的5.X经典版本。改天有空拷给你。
数据库要好好学习哦,正则表达式也要掌握,学好了可以进一步做程序的。

我们都在路上。。。。。
2012-03-09 16:15
ExcSpirit
Rank: 1
等 级:新手上路
帖 子:1
专家分:0
注 册:2012-3-13
得分:0 
谢谢 分享啊 。。。共享精神 必须值得赞扬!
2012-03-13 19:51



参与讨论请移步原网站贴子:https://bbs.bccn.net/thread-362514-1-1.html




关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.135756 second(s), 8 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved