Socket网络编程:文件传输

客户端发送文件名给服务器,服务器接受文件名,将对应的文件发送给客户端


 

基于TCP的Linux文件传输

客户端:

#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23334;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Linux】                      \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_ )            (_)      \n");
    printf("                                                            \n");
    /*
    客户端接收文件
    */
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            binner();
            menue();
            exit(-1);
        }
        else 
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    

    //步骤1:调用socket函数创建客户端TCP套接字;
    printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    int tsock;
    tsock = socket(AF_INET,SOCK_STREAM,0);
    if(tsock < 0)
    {
        printf("创建socket失败!\n");
        exit(-1);
    }
    //步骤2:找到期望与之通信的远程服务器端套接字的端点地址(即服务器端的IP地址和协议端口号);然后,调用connect函数向远程服务器端发起TCP连接建立请求;

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(struct sockaddr_in));

    servaddr.sin_family = AF_INET;
    inet_aton(SERVERIP,&servaddr.sin_addr);
    servaddr.sin_port = htons(SERVER_PORT);

    int ret;
    ret = connect(tsock,(struct sockaddr*)&servaddr,sizeof(struct sockaddr));
    if(ret < 0)
    {
        printf("连接失败!\n");
        exit(-1);
    }

    //步骤3:在与服务器端成功地建立了TCP连接之后,调用send()函数将缓冲区中的数据从套接字发送给该远程服务器端;
    char file_name[FILE_NAME_MAX_SIZE+1];
    memset(file_name,'\0',sizeof(file_name));
    printf("输入文件名>>");
    gets(file_name);
    char buffer[my_BUFSIZ];
    memset(buffer,'\0',sizeof(buffer));
    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));
    //向服务器发送buffer中的数据,buffer中放的是文件的名字
    int num = 0;
    num = send(tsock,buffer,strlen(buffer),0);
    if(num != strlen(buffer))
    {
        printf("发送数据失败!\n");
        exit(-1);
    }
    //步骤4:调用recv()函数从套接字读取服务器端发送过来的数据并存入缓冲区;
    FILE *fp = fopen(file_name,"w");
    if(fp==NULL)
    {
        printf("文件:%s不可打开\n",file_name);
        exit(-1);
    }
    memset(buffer,'\0',my_BUFSIZ);
    num = 0;
    while(num = recv(tsock,buffer,my_BUFSIZ,0)!=0)
    {
        if(num < 0)
        {
            printf("接收数据失败!\n");
            break;
        }
        int write_len = fwrite(buffer,sizeof(char),my_BUFSIZ,fp);
        //printf("接收文件长度:%d\n",num);
        if(write_len!=my_BUFSIZ)
        {
            printf("文件:%s写入失败\n",file_name);
            break;
        }
        memset(buffer,'\0',my_BUFSIZ);
    }
    printf("接收文件:%s成功\n",file_name);
    fclose(fp);
    //步骤5:与服务器端交互完毕,调用close()函数将套接字关闭,释放所占用的系统资源。
    close(tsock);
    return 0;
}

服务器:

#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
#include <netinet/in.h>
int SERVER_PORT = 23335 ;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Linux】                      \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
    /*
    服务器发送文件
    */
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            binner();
            menue();
            exit(-1);
        }
        else 
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    

    printf("【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    //步骤1:调用socket()函数创建服务器端TCP主套接字;
    int msock;
    msock = socket(AF_INET,SOCK_STREAM,0);
    if(msock<0)
    {
        printf("创建套接字失败");
        exit(-1);
    }
    //步骤2:调用bind()函数将该TCP套接字绑定到本机的一个可用的端点地址;

    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(struct sockaddr_in));

    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVER_PORT);

    int ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in));
    if(ret < 0)
    {
        printf("绑定服务器端口:%d失败\n",SERVER_PORT);
        exit(-1);
    }

    //步骤3:调用lsten函数将该TCP套接字设为被动模式,并设置等待队列的长度;
    #define QUEUE 20
    if(listen(msock,QUEUE)<0)
    {
        printf("监听失败!\n");
        exit(-1);
    }
    while(1)
    {
        //步骤4:调用accept()函数从该TCP套接字上接收一个新客户连接请求,并且在与该客户之间成功建立了TCP 连接之后,为该TCP连接创建个新的从套接字 (由该新套接字来负责与客户之间进行实际的通信);
        int ssock;
        struct sockaddr_in clientaddr;
        int len = sizeof(clientaddr);
        memset(&clientaddr,0,sizeof(struct sockaddr_in));
        ssock=accept(msock,(struct sockaddr*)&clientaddr,&len);
        if(ssock<0)
        {
             printf("接收数据失败\n");
             exit(-1);
        }
        //步骤5:基于新创建的从套接字,调用recv(函数从套接字读取客户发送过来的数据并存入缓冲区;

        char buffer[my_BUFSIZ];
        memset(buffer,'\0',sizeof(buffer));
        if(recv(ssock, buffer, sizeof(buffer), 0)<0)
        {
            printf("接收文件名失败\n");
            exit(-1);
        }
        else
        {
            printf("请求文件名>>%s\n",buffer);
        }

        //步骤6:基于新创建的从套接字,调用send()函 数将缓冲区中的数据从套接字发送给该远程客户:

        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        //将文件名从缓冲区buffer拷贝到文件名数组里面
        strncpy(file_name,buffer,strlen(buffer)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buffer));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件:%s不存在\n",file_name);
        }
        else
        {
            memset(buffer,'\0',my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buffer,sizeof(char),my_BUFSIZ,fp))>0)
            {
                printf("文件块大小:%d\n",file_block_length);
                if(send(ssock,buffer,file_block_length,0)<0)
                {
                    printf("文件:%s 发送失败\n",file_name);
                    break;
                }
                memset(buffer,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("发送文件:%s 成功\n",file_name);
        }

       //步骤7:与客户交互完毕,调用close()函数将从套接字关闭,释放所占用的系统资源;
        close(ssock);
    }
   //步骤8:与所有客户交互完毕,调用close()函数将主套接字关闭,释放所占用的系统资源
    close(msock);
    return 0;
}

 基于UDP的Linux文件传输

服务器:

#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <netinet/in.h>
#include <stdlib.h>
int  my_BUFSIZ=4096;
int  SERVER_PORT=23334;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Linux】                      \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            exit(-1);
        }
        else 
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    
     printf("【UDP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    //步骤1: 调用socket()函数创建服务器端UDP套接字;
    int msocket;
    msocket = socket(AF_INET,SOCK_DGRAM,0);
    if(msocket<0)
    {
        printf("创建套接字失败");
        exit(-1);
    }

    //步骤2:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址;

    int ret;
    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(struct sockaddr_in));
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVER_PORT);
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    ret=bind(msocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr_in));
    if(ret<0)
    {
        printf("服务器绑定端口:%d失败",SERVER_PORT);
        exit(-1);

    }
    //步骤3:调用recvfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存;
    while(1)
    {
        char buf[my_BUFSIZ];
        memset(buf,'\0',sizeof(buf));
        struct sockaddr_in clientaddr;
        int len = sizeof(clientaddr);
        memset(&clientaddr,0,sizeof(struct sockaddr_in));

        if(recvfrom(msocket, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len)<0)
        {
            printf("接收数据失败\n");
            exit(-1);
        }
        else
        {
            printf("请求文件名>>%s\n",buf);
        }
        
        //步骤4:基于保存的远程客户端的套接字端点地址,调用sendto函数将缓冲区中的数据从该UDP套接字发送给该远程客户端;
        char file_name[FILE_NAME_MAX_SIZE+1];
        memset(file_name,'\0',sizeof(file_name));
        //将文件名从缓冲区buf拷贝到文件名数组里面
        strncpy(file_name,buf,strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buf));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件:%s不存在\n",file_name);
        }
        else
        {
            memset(buf,'\0',my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buf,sizeof(char),my_BUFSIZ,fp))>0)
            {
                printf("文件块大小:%d\n",file_block_length);
                if(sendto(msocket,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)!=strlen(buf))
                {
                    printf("文件:%s 发送失败\n",file_name);
                    break;
                }
                memset(buf,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("发送文件:%s 成功\n",file_name);
        
        
        }
    }
    
    //步骤5:与客户交互完毕,调用close()函数将该 UDP套接字关闭,释放所占用的系统资源。
    close(msocket);
    return 0;
 }

客户端:

#include <stdio.h>
#include <sys/socket.h>
#include <string.h>
#include <arpa/inet.h>
#include <stdlib.h>
#include <string.h>
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23334;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Linux】                       \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
         
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    printf("【UDP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    //步骤1:调用socket()函数创建客户端UDP套接字;
    int tsock;
    tsock = socket(AF_INET,SOCK_DGRAM,0);
    if(tsock < 0)
    {
        printf("创建套接字失败\n");
        exit(-1);
    }
    //步骤2:找到期望与之通信的远程服务器的IP地址和协议端口号,然后再调用sendto()函数将缓冲区中的数据从UDP套接字发送给远程服务器端;
    char file_name[FILE_NAME_MAX_SIZE+1];
    memset(file_name,'\0',sizeof(file_name));
    printf("输入文件名>>");
    gets(file_name);
    
    char buffer[my_BUFSIZ];
    memset(buffer,'\0',sizeof(buffer));
    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));
    
    struct sockaddr_in servaddr;
    memset(&servaddr,0,sizeof(struct sockaddr_in));
    servaddr.sin_family = AF_INET;
    inet_aton(SERVERIP,&servaddr.sin_addr);
    servaddr.sin_port = htons(SERVER_PORT);
    int len = sizeof(struct sockaddr_in);
    //printf("buffer:%d",strlen(buffer));
    int send_to=sendto(tsock,buffer,strlen(buffer),0,(struct sockaddr*)&servaddr,len);
    printf("%d,%d",send_to,strlen(buffer));
    if(send_to != strlen(buffer))
    {
        printf("发送数据失败\n");
        exit(-1);
    }

    FILE *fp = fopen(file_name,"w");
    if(fp==NULL)
    {
        printf("文件:%s不可打开\n",file_name);
        exit(-1);
    }
    
    int num = 0;

    char buf[my_BUFSIZ];
    memset(buf,'\0',my_BUFSIZ);
    struct sockaddr_in clientaddr;
    memset(&clientaddr,0,sizeof(struct sockaddr_in));
    memset(buf,'\0',sizeof(buf));
    //步骤3:调用revfrom()函数从该UDP套接字接收来自远程服务器端的数据并存入缓冲区;
    while(num = recvfrom(tsock,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len) !=0)
    {
        if( num< 0)
        {
           printf("接收数据失败\n");
           exit(-1);
        }
        int write_len = fwrite(buf,sizeof(char),my_BUFSIZ,fp);
        //printf("接收文件长度:%d\n",num);
        if(write_len!=my_BUFSIZ)
        {
            printf("文件:%s写入失败\n",file_name);
            break;
        }
        memset(buf,'\0',my_BUFSIZ);    
    }
    printf("接收文件:%s成功\n",file_name);
    fclose(fp);
    close(tsock);

    return 0;
}

 基于UDP的Windows文件传输:

客户端:

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23334;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Linux】                      \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {

            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    printf("【UDP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    //初始化Winsock DLL
    int ret;
    WORD sockertVersion=MAKEWORD(2, 2);
    WSADATA wsaData;
    ret = WSAStartup(sockertVersion, &wsaData);
    if(ret!=0)
    {
        printf("无法打开winsock.dll!\n");
        exit(-1);
    }
    //创建socket
    SOCKET tsocket = socket(AF_INET, SOCK_DGRAM, 0);
    if(tsocket == INVALID_SOCKET)
    {
        printf("创建socket失败!");
        exit(-1);
    }
    //绑定和发送数据
    char file_name[FILE_NAME_MAX_SIZE+1];
    memset(file_name,'\0',sizeof(file_name));
    printf("输入文件名>>");
    gets(file_name);

    char buffer[my_BUFSIZ];
    memset(buffer,'\0',sizeof(buffer));
    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));

    struct sockaddr_in servaddr;
    ZeroMemory(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr=inet_addr(SERVERIP);
    servaddr.sin_port = htons(SERVER_PORT);
    int num=0;
    int len = sizeof(struct sockaddr_in);
    num = sendto(tsocket,buffer, strlen(buffer) , 0, (struct sockaddr*)&servaddr, len);
    if(num!=strlen(buffer))
    {
        printf("发送数据失败!");
        exit(-1);
    }
    //接收数据
    FILE *fp = fopen(file_name,"w");
    if(fp==NULL)
    {
        printf("文件:%s不可打开\n",file_name);
        exit(-1);
    }


    char buf[my_BUFSIZ];
    ZeroMemory(buf,sizeof(buf));
    num=0;
    struct sockaddr_in clientaddr;
    ZeroMemory(&clientaddr,sizeof(clientaddr));

    while(num = recvfrom(tsocket,buf,sizeof(buf),0,(struct sockaddr*)&clientaddr,&len)!=0)
    {
        if(num<0)
        {
            printf("接收数据失败");
            exit(-1);
        }
       int write_len = fwrite(buf,sizeof(char),my_BUFSIZ,fp);
        //printf("接收文件长度:%d\n",num);
        if(write_len!=my_BUFSIZ)
        {
            printf("文件:%s写入失败\n",file_name);
            break;
        }
        memset(buf,'\0',my_BUFSIZ);
    };
    printf("接收文件:%s成功\n",file_name);
    closesocket(tsocket);
    WSACleanup();
    system("pause");

    return 0;
}

 

服务器:

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
int  my_BUFSIZ=4096;
int  SERVER_PORT=23334;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Windows】                    \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
     binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }

    printf("【UDP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    //步骤1:使用WSAStartup函数初始化Winsock DLL;
    WORD scoketVersion;
    scoketVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    int ret = WSAStartup(scoketVersion, &wsaData);
    if(ret != 0 )
    {
        printf("无法打开 winsock.dll!\n");
        exit(-1);
    }
    //步骤2:调用socket函数创建服务器端UDP套接字;
    SOCKET msock;
    msock = socket(AF_INET, SOCK_DGRAM, 0);
    if(msock == INVALID_SOCKET)
    {
        printf("创建socket失败!");
        exit(-1);
    }
    //步骤3:调用bind()函数将该UDP套接字绑定到本机的一个可用的端点地址:

    struct sockaddr_in servaddr;
    ZeroMemory(&servaddr,sizeof(servaddr));
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVER_PORT);
    if(bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in))< 0)
    {
        printf("绑定服务器端口:%d失败\n",SERVER_PORT);
        exit(-1);
    }
    while(1)
    {
        //步骤4:调用revfrom函数从该UDP套接字接收来自远程客户端的数据并存入缓冲区,同时获得远程客户端的套接字端点地址并保存;
        char buf[my_BUFSIZ];
        ZeroMemory(buf,sizeof(buf));
        struct sockaddr_in clientaddr;
        int len = sizeof(clientaddr);
        ZeroMemory(&clientaddr,sizeof(clientaddr));

        int num = recvfrom(msock, buf, sizeof(buf), 0, (struct sockaddr*)&clientaddr, &len);
        if(num<0)
        {
            printf("接收数据失败\n");
            exit(-1);
        }
        else
        {
            printf("请求文件名>>%s\n",buf);
        }

        //步骤5:基于保存的远程客户端的套接字端点地址,调用sendto()函 数将缓冲区中的数据从该UDP套接字发送给该远程客户端;
        char file_name[FILE_NAME_MAX_SIZE+1];
        ZeroMemory(file_name,sizeof(file_name));

        strncpy(file_name,buf,strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buf));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件:%s不存在\n",file_name);
        }
        else
        {
            ZeroMemory(buf,sizeof(buf));
            int file_block_length=0;
            while((file_block_length=fread(buf,sizeof(char),my_BUFSIZ,fp))>0)
            {
                printf("文件块大小:%d\n",file_block_length);
                if(sendto(msock,buf,strlen(buf),0,(struct sockaddr*)&clientaddr,len)!=strlen(buf))
                {
                    printf("文件:%s 发送失败\n",file_name);
                    break;
                }
                memset(buf,'\0',my_BUFSIZ);
            }
            fclose(fp);
            printf("发送文件:%s 成功\n",file_name);
        }
    }
    //步骤6:与客户交互完毕,调用closesocket()函数将该UDP套接字关闭,释放所占用的系统资源;
    closesocket(msock);
    //步骤7:最后,调用WSACleanup0函数结束Winsock Socket API。
    WSACleanup();
    system("pause");

    return 0;
}

 基于TCP的Window文件传输:

客户端:

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
char *SERVERIP="127.0.0.1";
int SERVER_PORT=23334;
int my_BUFSIZ=4096;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Windows】                    \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-l:服务器地址,默认127.0.0.1\n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-l")==0)
                {
                    SERVERIP = argv[i+1];
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }
    printf("【TCP客户端:目标IP %s,监听端口 %d,发送数据大小:%d,发送文件名最大:%d】\n\n",SERVERIP,SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
    //步骤1:使用WSAStartup()函数初始化Winsock DLL;
    int ret;
    WORD socketVersion=MAKEWORD(2, 2);
    WSADATA wsaData;
    ret = WSAStartup(socketVersion, &wsaData);
    if(ret!=0)
    {
        printf("无法打开winsock.dll!\n");
        exit(-1);
    }

    //步骤2:调用socket()函数创建客户端TCP套接字;
    SOCKET tsocket = socket(AF_INET, SOCK_STREAM, 0);
    if(tsocket == INVALID_SOCKET)
    {
        printf("创建socket失败!");
        exit(-1);
    }

    //步骤3:找到期望与之通信的远程服务器端套接字的端点地址(即远程服务器端的IP地址和协议端口号),
    //然后再调用connect()函数向远程服务器端发起TCP连接建立请求;
    struct sockaddr_in servaddr;
    ZeroMemory(&servaddr,sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr=inet_addr(SERVERIP);
    servaddr.sin_port = htons(SERVER_PORT);

    if(connect(tsocket,(struct sockaddr*)&servaddr,sizeof(struct sockaddr))<0)
    {
        printf("连接失败!");
        exit(-1);
    }

    //步骤4:在与服务器端成功地建立了TCP连接之后,
    //调用send()函数将缓冲区中的数据从该TCP套接字发送给该远程服务器端;
    char file_name[FILE_NAME_MAX_SIZE+1];
    memset(file_name,'\0',sizeof(file_name));
    printf("输入文件名>>");
    gets(file_name);
    char buffer[my_BUFSIZ];
    memset(buffer,'\0',sizeof(buffer));
    strncpy(buffer,file_name,strlen(file_name)>my_BUFSIZ ? my_BUFSIZ:strlen(file_name));
//    char *buffer="这里是客户端~";
    int num=0;
    num = send(tsocket,buffer, strlen(buffer),0);
    if(num!=strlen(buffer))
    {
        printf("发送数据失败!");
        exit(-1);
    }
    FILE *fp = fopen(file_name,"w");
    if(fp==NULL)
    {
        printf("文件:%s不可打开\n",file_name);
        exit(-1);
    }

    //步骤5:调用recv()函数从该TCP套接字读取服务器端发送过来的数据并存入缓冲区;
    ZeroMemory(buffer,sizeof(buffer));
    num = 0;
    while(num = recv(tsocket,buffer,sizeof(buffer),0)!=0)
    {
        if(num<0)
        {
            printf("接收数据失败\n");
            exit(-1);
        }
        int write_len = fwrite(buffer,sizeof(char),my_BUFSIZ,fp);
        printf("接收文件长度:%d\n",num);
        if(write_len!=my_BUFSIZ)
        {
            printf("文件:%s写入失败\n",file_name);
            break;
        }
        memset(buffer,'\0',my_BUFSIZ);
    }
    printf("接收文件:%s成功\n",file_name);
    fclose(fp);
    //步骤6:与服务器端交互完毕,调用closesocket()函数将该 TCP套接字关闭并释放所占用的系统资源;
    closesocket(tsocket);
    //步骤7:最后,调用WSACleanup()函数结束Winsock Socket API。
    WSACleanup();
    system("pause");

    return 0;
}

 

服务器端:

#include <stdio.h>
#include <WinSock2.h>
#pragma comment(lib, "ws2_32.lib")
int my_BUFSIZ=4096;
int  SERVER_PORT=23334;
int FILE_NAME_MAX_SIZE=512;
void binner()
{
    printf("               【文件传输助手:Windows】                    \n");
    printf("    _  _  _  _           _           _        _           _ \n");
    printf("   (_)(_)(_)(_) _       (_)_       _(_)      (_)_       _(_)\n");
    printf("   (_)         (_)        (_)_   _(_)          (_)_   _(_)  \n");
    printf("   (_) _  _  _ (_)          (_)_(_)              (_)_(_)    \n");
    printf("   (_)(_)(_)(_)              _(_)_                 (_)      \n");
    printf("   (_)   (_) _             _(_) (_)_               (_)      \n");
    printf("   (_)      (_) _        _(_)     (_)_             (_)      \n");
    printf("   (_)         (_)      (_)         (_)            (_)      \n");
    printf("                                                            \n");
}
void menue()
{
    printf("\n使用说明:\n");
    printf("-h:帮助 \n");
    printf("-p:端口,默认23334 \n");
    printf("-b:发送数据大小,默认4096\n");
    printf("-f:文件最大,默认512\n");
}
int main(int argc,char *argv[])
{
    binner();
    menue();
    if(argc>1)
    {
        if(strcmp(argv[1],"-h")==0)
        {
            exit(-1);
        }
        else
        {
            for(int i=1;i<argc;++i)
            {
                if(strcmp(argv[i],"-p")==0)
                {
                    SERVER_PORT=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-b")==0)
                {
                    my_BUFSIZ=atoi(argv[i+1]);
                }
                else if(strcmp(argv[i],"-f")==0)
                {
                    FILE_NAME_MAX_SIZE=atoi(argv[i+1]);
                }
            }

        }
    }


    printf("\n【TCP服务端:监听端口 %d,发送数据大小:%d,发送文件最大:%d】\n\n",SERVER_PORT,my_BUFSIZ,FILE_NAME_MAX_SIZE);
      WORD scoketVersion;
    scoketVersion = MAKEWORD(2, 2);
    WSADATA wsaData;
    int ret = WSAStartup(scoketVersion, &wsaData);
    if(ret != 0 )
    {
        printf("无法打开 winsock.dll!\n");
        exit(-1);
    }

    //步骤2:调用socket()函数创建服务器端TCP主套接字;
    SOCKET msock;
    msock = socket(AF_INET, SOCK_STREAM, 0);
    if(msock == INVALID_SOCKET)
    {
        printf("创建socket失败!");
        exit(-1);
    }

    //步骤3:调用bind()函数将TCP主套接字绑定到本机的一个可用的端点地址:
    struct sockaddr_in servaddr;
    ZeroMemory(&servaddr,sizeof(servaddr));

    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(SERVER_PORT);
    ret = bind(msock, (struct sockaddr*)&servaddr, sizeof(struct sockaddr_in));
    if(ret < 0)
    {
        printf("绑定服务器端口:%d失败\n",SERVER_PORT);
        exit(-1);
    }

    //步骤4:调用listen()函数将该TCP主套核字设为被动模式,并设置等待队列长度:
    #define QUEUE 20
    if(listen(msock,QUEUE)<0)
    {
        printf("监听失败!");
        exit(-1);
    }

    //步骤5:调用accpet()函数从该TCP主套接字上接收一个新的客户 TCP连接请求,
    //并在与该客户之间成功建立了TCP连接之后,为该TCP连接创建一一个新的从套接字
    //(由该新的从套接字来负责与客户之间进行实际的通信);
    while(1)
    {
        SOCKET ssock;
        struct sockaddr_in clientaddr;
        int len = sizeof(clientaddr);
        ZeroMemory(&clientaddr,sizeof(clientaddr));
        ssock=accept(msock,(struct sockaddr*)&clientaddr,&len);
        if(ssock==INVALID_SOCKET)
        {
             printf("接收数据失败\n");
             exit(-1);
        }

        //步骤6:基于新创建的从套接字,调用recv()函数利用 该从套接字读取客户端发送过来的数据并存入缓冲区;
        char buf[my_BUFSIZ];
        ZeroMemory(buf,sizeof(buf));
        if(recv(ssock, buf, sizeof(buf), 0)<0)
        {
            printf("接收文件名失败\n");
            exit(-1);
        }
        else
        {
            printf("请求文件名>>%s\n",buf);
        }

        //步骤7:基于新创建的从套接字,调用send()函数将缓冲区中的数据利用该从套接字发送给该远程客户端;
        //char *buffer="这里是服务器~";
        char file_name[FILE_NAME_MAX_SIZE+1];
        ZeroMemory(file_name,sizeof(file_name));
        //将文件名从缓冲区buffer拷贝到文件名数组里面
        strncpy(file_name,buf,strlen(buf)>FILE_NAME_MAX_SIZE ? FILE_NAME_MAX_SIZE:strlen(buf));
        FILE * fp=fopen(file_name,"r");
        if(fp==NULL)
        {
            printf("文件:%s不存在\n",file_name);
        }
        else
        {
            ZeroMemory(buf,my_BUFSIZ);
            int file_block_length=0;
            while((file_block_length=fread(buf,sizeof(char),my_BUFSIZ,fp))>0)
            {

                if(send(ssock,buf,file_block_length,0)<0)
                {
                    printf("文件:%s 发送失败\n",file_name);
                    break;
                }
                ZeroMemory(buf,my_BUFSIZ);
            }
            fclose(fp);
            printf("发送文件:%s 成功\n",file_name);
        }
       //步骤8:与客户交互完毕,调用closesocket()函数将该从套接字关闭,释放所占用的系统资源);

        closesocket(ssock);

        //步骤9:最后,当与所有客户交互完毕之后,调用closesocket()函数将TCP主套接字关闭,
        //释放所古用的系统资源,然后,再调用WSACleanup()函数来结束Winsock Socket API
    }
    closesocket(msock);
    WSACleanup();

    system("pause");

    return 0;
}

 

posted @ 2020-10-12 12:50  东坡肉肉君  阅读(173)  评论(0编辑  收藏  举报