当前位置: 移动技术网 > IT编程>开发语言>C/C++ > C语言socket实现文件下载

C语言socket实现文件下载

2018年10月13日  | 移动技术网IT编程  | 我要评论

重生之都市狂龙txt,宠物兔子名字,dhl快件查询

是网络的作业,我比较菜。写到定位输出,做百分比出现了问题,不显示0到100的,直接从0跳到了100。请教了下大佬。改了过来。原来是类型的问题,做出来的运算应该是float,但是我都定义的int,输出也是,大佬指出后,我好尴尬。犯了小错误。但是在这次过程也学习了一波。要加油了!代码写的这么乱!
写的是带颜色的版本,颜色有可能会觉得妖艳,好吧。
编译平台是++6.0

还是有点bug,有时,客户端发dir命令时会退出。有空再看看。这几天太忙。萌新的我只会点c,不会c++。如有错误,望大佬指出。谢谢。

sever:

#include
#include
#include
#include
#include
#include
#include  
#pragma comment(lib,"ws2_32.lib")
using namespace std;
#define default_buflen 512
#define default_port   8088
#define buffer_size 4096
char    sendbuffer[buffer_size],recvbuffer[buffer_size];   //发送缓冲区及接收缓冲区
socket          acceptsocket;
dword winapi clientthread(lpvoid lp);
struct clientinfo{
    socket          clientsocket;
    sockaddr_in     sockaddr;
};

int main(int argc, tchar* argv[])
{
    int         ret;
    wsadata     wsadata;

    if((ret = wsastartup(makeword(2,2),&wsadata)) != no_error)
    {
        printf("wsastartup failed with error %d\n",ret);
        return -1;
    }//if

    // create a new socket to listening for client connections.
    socket      listensocket;
    if((listensocket = socket(af_inet,sock_stream,ipproto_tcp)) 
        == invalid_socket)
    {
        printf("socket failed with error %d\n",wsagetlasterror());
        wsacleanup();
        return -1;
    }//if

    sockaddr_in     service;
    service.sin_family = af_inet;
    service.sin_addr.s_addr = inet_addr("127.0.0.1");
    service.sin_port = htons(default_port);

    if(bind(listensocket,(sockaddr* ) &service,sizeof(service)) == socket_error)
    {
        printf("bind failed with error %d\n",wsagetlasterror());
        closesocket(listensocket);
        wsacleanup();
        return -1;
    }//if

    if(listen(listensocket, 10) == socket_error)
    {
        printf("error listening on socket.\n");
        closesocket(listensocket);
        wsacleanup();
        return -1;
    }//if

    socket          acceptsocket;
    sockaddr_in     clientaddr;//接收客户端地址
    int     addrclientlen = sizeof(clientaddr);
    while(true)
    {

        clientinfo      clientinfo;
        printf("waiting for client to connect......\n");
        acceptsocket = accept(listensocket,(sockaddr* ) &clientaddr, &addrclientlen);
        if(acceptsocket == invalid_socket)
        {
            printf("accept failed : %d\n",wsagetlasterror());
            closesocket(listensocket);
            wsacleanup();
            return 1;
        }//if
        clientinfo.clientsocket = acceptsocket;
        memcpy(&clientinfo.sockaddr,&clientaddr,sizeof(sockaddr_in));
        printf("a client is coming......\n");
        dword dwthreadid;
        createthread(null,0,clientthread,(lpvoid* )&clientinfo,0,&dwthreadid);
    }//while
    closesocket(listensocket);
    wsacleanup();
    return 0;
} //main
dword winapi clientthread(lpvoid lp)
{
    clientinfo *pclientinfo = (clientinfo* )lp;
    socket  clientsocket = pclientinfo->clientsocket;
    sockaddr_in sockaddr;
    memcpy(&sockaddr,&pclientinfo->sockaddr,sizeof(sockaddr_in));
    int     iresult,bytes;
    char    recvrfilename[default_buflen] = "";
    char    temp_buffer[buffer_size];
    unsigned readlen;
    dword dwreadsize = 0;
    char   curpath[max_path]; 
    char quit [10] ="quit";
    //获得相对路径
    getmodulefilename(null,(lpstr)curpath,sizeof(curpath));
    strrchr( curpath, '\\')[0]= 0;

    ifstream infile;
    while(true)
    {
        memset(recvrfilename,0,sizeof(recvrfilename));
        iresult = recv(clientsocket,recvrfilename,default_buflen,0);
        if(socket_error == iresult)
        {
            printf("recvieve failed with error : %d\n",wsagetlasterror());
            closesocket(clientsocket);
            wsacleanup();
            return -1;
        }//if


        //命令有get help exit -s(文件大小)

        //help
        char dir [10] ="dir";
        char get [10] ="get";
        printf("传过来的数据:%s",recvrfilename);

        if(strcmp(recvrfilename,dir)==0){
        //返回命令
        system("cmd /c dir /a-d /b >allfiles.txt");
        printf("查看allfiles文件\n");

            //将打印出来的文件信息读取出来

        file *file;
char buf[1024];
int len=0,i=0;
char *array[1024];
char filedir [1024];//要传过去的文件目录

file=fopen("allfiles.txt","r");//打开txst.txt文件
if(!file)return -1;
while(fgets(buf,1024,file))//读取txt中字符
{
 len=strlen(buf);
 array[i]=(char*)malloc(len+1);
 if(!array[i])break;
 strcpy(array[i++],buf);
}//while

fclose(file);
i--;
while(i>=0&&array[i])
{
 printf("%s\n",array[i]);//打印test文档的字符

    iresult = send(clientsocket,array[i],strlen(array[i]),0);
    if(iresult==socket_error){printf("发送失败\n");}

    free(array[i--]);

}//while
        printf("发送结束quit\n");
    send(clientsocket,quit,strlen(quit),0);
            continue;

        }//if

        //完整文件名
        strcat(curpath,"\\");
        strcat(curpath,recvrfilename);
        strcpy( recvrfilename,curpath);



                        //获取文件大小

        file * pfile;
      long size;
      pfile = fopen (recvrfilename,"rb");
      if (pfile==null)
            perror ("error opening file");
      else
      {
            fseek (pfile, 0, seek_end);   ///将文件指针移动文件结尾
            size=ftell (pfile); ///求出当前文件指针距离文件开始的字节数
            fclose (pfile);
            printf ("filesize : %ld bytes.\n",size);
                char a[30];
                //将size保存在字符串a中
            sprintf(a,"%d",size);
            send(clientsocket, a, 30, 0);
                printf("发送文件大小:%s",a);
      }


        printf("文件:%s\n",recvrfilename);
        infile.open(recvrfilename,ios::in|ios::binary);

        if(!infile)
        {    //未成功打开文件
            printf("sorry, cannot open %s. please try again.\r\n",recvrfilename);
            //break;
        }//if

        else
        {
            printf("the file %s is found,ready to transfer.\n",recvrfilename);
            printf("transfering\r\n"); 



            while (!infile.eof())
            {    //循环读取文件并通过h_newsocket发送到客户端
                //printf(sendbuffer,"%s",temp_buffer); 
                infile.read(sendbuffer,buffer_size);
                readlen = infile.gcount();
                send(clientsocket, sendbuffer, readlen, 0);
                //printf("."); 
            }
            infile.close();
            printf("transfer completed... \r\n"); 


            //bytes = send(acceptsocket, sendbuffer, strlen(sendbuffer), 0);

        }//else      




    //如果没有数据发送
    iresult = shutdown(clientsocket,sd_both);
    if (iresult == socket_error) {
        printf("shutdown failed: %d\n", wsagetlasterror());
    }//if

    closesocket(clientsocket);
    return 0;


    }//while
}//main

client:

#include
#include
#include
#include
#include
#include
#include

using namespace std;

#pragma comment(lib,"ws2_32.lib")

#define default_buflen 512
#define default_port   5150
#define buffer_size 4096

int main(int argc, tchar* argv[])
{
    int         iresult,rec;
    wsadata     wsadata;
    handle hout;
    ofstream    outfile;
    socket connectsocket = invalid_socket;
    struct sockaddr_in clientservice;
    char    sendbuf[default_buflen] = "";
    char    szbuffer[buffer_size];
    bool    issend = true;

    //初始化windows sockets dll
    if(iresult = wsastartup(makeword(2,2),&wsadata) != no_error)
    {
        printf("wsastartup failed with error : %d\n",iresult);
        return -1;
    }
    //创建socket
    connectsocket = socket(af_inet,sock_stream,ipproto_tcp);
    if(connectsocket == invalid_socket)
    {
        printf("socket failed with error : %d\n",wsagetlasterror());
        wsacleanup();
        return -1;
    }
    ////////////////////

     char addr[20];
   int prot ;
   printf("现在运行的是客户端!\n");
   printf("**************************************************************\n");
   printf("请输入服务器的ip地址:");
   scanf("%s",addr);
   printf("请输入服务器的端口:");
    scanf("%d",&prot);



    ///////////////////


    //设置目的网络地址并连接服务器
    clientservice.sin_family = af_inet;
    clientservice.sin_addr.s_addr = inet_addr(addr);
    clientservice.sin_port = htons(prot);
    iresult = connect(connectsocket,(sockaddr* )&clientservice,sizeof(clientservice));
    if(iresult == socket_error)
    {
        printf("connect failed with error : %d\n",wsagetlasterror());
        closesocket(connectsocket);
        wsacleanup();
        return -1;
    }

    printf("connect with server successfully!!!\n");
                hout = getstdhandle(std_output_handle);  
 setconsoletextattribute(hout,  
                            foreground_green);   
        cout<<"输入命令:******************* help 获取命令提示**********************:\n";
    while(true)
    {



        //输入命令:
        char cmd [20];
        char help [10] ="help";
        char exit [10] ="exit";
        char get [10] ="get";
        char dir [10] ="dir";
        char quit [10] ="quit";
        scanf("%s",&cmd);
        printf("输入的命令是%s\n",cmd);
        if(strcmp(cmd,help)==0){


            printf("命令参数:\n help----------获取命令帮助\n dir----------获取文件目录\n get----------下载文件\n exit----------退出\n");
                continue;
        }
        //  列目录
        if(strcmp(cmd,dir)==0){

        iresult = send(connectsocket,dir,strlen(dir),0);

        if(socket_error == iresult)
        {
            printf("send failed with error : %d\n",wsagetlasterror());
            closesocket(connectsocket);
            wsacleanup();
            return -1;
        }
        //接收传过来的目录

        setconsoletextattribute(hout,  
                            foreground_green |   
                            foreground_blue);  
        printf("**********************文件目录**********************\n");
        char dirs [30];


        while(true){
                zeromemory(dirs,30);
            iresult = recv(connectsocket,dirs,30,0);
            //数据发送完成就跳出循环,结束时,服务器发过来quit
            if(strcmp(dirs,quit)==0){break;}

            else
            printf("%s\n",dirs);


            if(socket_error == iresult)
        {
            printf("recvieve failed with error : %d\n",wsagetlasterror());
            closesocket(connectsocket);
            wsacleanup();
            return -1;
        }//if

                        //接收完再次返回
                //  continue;
        }//while
            continue;
        }//if



        if(strcmp(cmd,exit)==0){break;}

        if(strcmp(cmd,get)==0){
            setconsoletextattribute(hout, foreground_intensity | foreground_red); 
            printf("您输入的命令是get,下载文件,请依次输入要下载的文件名、保存本地文件名\n");





        //文件下载   参数get后使用
        char  str[20];
        //文件名
        scanf("%s",&str);
        zeromemory(sendbuf,default_buflen);
        strcpy(sendbuf,str);
        if(strcmp(str,quit)==0){



        printf("您输入了exit,退出get\n");
            continue;
        }

            setconsoletextattribute(hout,  
                            foreground_red |   
                            foreground_green |   
                            foreground_blue);  
        iresult = send(connectsocket,sendbuf,strlen(sendbuf),0);
        if(socket_error == iresult)
        {
            printf("send failed with error : %d\n",wsagetlasterror());
            closesocket(connectsocket);
            wsacleanup();
            return -1;
        }

        //接收文件总大小
            int size;
            char sizestr [30];
            recv(connectsocket,sizestr,30,0);
            size = strtol (sizestr,null,10);

                setconsoletextattribute(hout,  
                            foreground_blue |   
                            foreground_red);

            printf("总的数据大小:%ld\n",size);

        //cout<<"输入存放文件(路径+文件名):\n";
        char    cfilename[default_buflen] = "";
            scanf("%s",&cfilename);


        setconsoletextattribute(hout, foreground_intensity|foreground_red|foreground_blue|foreground_green );

        printf("保存文件:%s\n",cfilename);

        outfile.open(cfilename,ios::out|ios::binary);

        if(!outfile)   //打开文件准备写入
        {    
            printf("error of opening file !");

            iresult = shutdown(connectsocket, sd_send);
            iresult = closesocket(connectsocket);
            wsacleanup();
            return -1;
        }


        coord   coord;

        console_screen_buffer_info csbi;

        hout=getstdhandle(std_output_handle);
        getconsolescreenbufferinfo(hout,&csbi);
        coord.x =csbi.dwcursorposition.x;
        coord.y =csbi.dwcursorposition.y;

        float cnt = 0;

        while(issend)
        {
            //读取流       

            rec = recv(connectsocket,szbuffer,buffer_size,0);
            cnt+=rec;
            if(rec == 0)
            {
                setconsoletextattribute(hout, foreground_intensity | foreground_red);
                printf("download completed ! \n");
                break;
            }
            else if(rec == socket_error)
            {
                printf("receive function failed with error : %d\n ",wsagetlasterror());
                break;
            }

            setconsolecursorposition(hout,coord);   
            setconsoletextattribute(hout, foreground_intensity | foreground_green);

            printf("received %f%% bytes \n",cnt/size*100);
            outfile.write(szbuffer,rec);            

        }

        setconsoletextattribute(hout, foreground_intensity | foreground_blue);
        printf("transfer is completed!\n");
        setconsoletextattribute(hout, foreground_intensity|foreground_red|foreground_blue|foreground_green );

        outfile.close();    

    }

    // 若没有数据要发送,单向关闭连接
    iresult = shutdown(connectsocket, sd_send);
    // step 6: 关闭连接
    iresult = closesocket(connectsocket);

    wsacleanup();
    return 0;

}
}

效果:

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网