JoJo Joheng 2020-06-26 18:14 采纳率: 0%
浏览 153

基于socket重复发送文件的问题

第一次发送还好
第二次发送文件
因为用循环结构的关系
客户端还没发送传送文件的信息,客户端就接受了信息。

客户端代码如下

#include "stdio.h"
#include "stdlib.h"
#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")
#define SERVERIP "127.0.0.1"
#define SERVERPORT 3333
#define SIZE 1024//4096
#define BUFSIZE 1024//4096

int SendFile(SOCKET sock,char filename[512]);
int main(void)
{
    printf("这里是客户端,正在为你连接服务器··\n");
    int ret,len;
    WSADATA data;
    SOCKET sockClient;
    struct sockaddr_in addrServer;
    char filename[512];//最终的文件的绝对位置
    char fpath_1[512];//用户输入的文件路径
    char fflag[512]="\\\\"; 
    char abs[512]="\\\\";   
    char fname[512];//用户输入的文件名字
    char fankui[512];

    char queren[1];




    ret=WSAStartup(MAKEWORD(2,2),&data);
    if (SOCKET_ERROR==ret)
    {
        printf("发生了错误:本地Winsock初始化失败\n");
        return -1;
    }
    printf("··");
    sockClient=socket(AF_INET,SOCK_STREAM,0);
    if (INVALID_SOCKET==sockClient)
    {
        printf("发生了错误:本地套接口创建失败\n");
        WSACleanup();
        return -2;
    }
    printf("··");
    memset(&addrServer,0,sizeof(struct sockaddr_in));
    addrServer.sin_family=AF_INET;
    addrServer.sin_addr.S_un.S_addr=inet_addr(SERVERIP);
    addrServer.sin_port=htons(SERVERPORT);

    len=sizeof(struct sockaddr);
    ret=connect(sockClient,(sockaddr*)&addrServer,len);
    if (SOCKET_ERROR==ret)
    {
        printf("发生了错误:连接服务器失败\n");
        closesocket(sockClient);
        WSACleanup();
        return -3;
    }
    printf("··");
    printf("成功\n");




    int again=1;
    int againflag=0;
    ///////////////////////////


    while(again==1)
    {
        if(againflag==1)
        {   
        ret=recv(sockClient,fankui,sizeof(fankui),0);
        printf("%s\n",fankui);
        memset(fankui,0,sizeof(fankui));

        }

     printf("请输入你要转送的该文件的路径\n");
     scanf("%s",fpath_1);
     int pathlen = 0;
     char flag = '\\';
     pathlen = strlen(fpath_1);

    for(int i = 0,y=0; i < pathlen; i++)
    {

        if(fpath_1[i] == flag )
        {   
            pathlen = pathlen + 1;
            filename[y]=flag;
            filename[y+1]=flag;         
            y = y+2;
        }
        else{
             filename[y]= fpath_1[i];
             y++;
        }
    }
    printf("请输入请输入该文件名(带后缀名)");
    scanf("%s",fname);
    strcat(fflag,fname);
    strcat(filename,fflag);
    printf("编译器中文件的路径:  %s\n",filename);

    SendFile(sockClient,filename);
    printf("\n");
    printf("传送结束,输入1继续传送新文件,输入2结束");
    scanf("%d",&again);
    if(again==1)
    queren[1]='1';
    else
    queren[1]='2';
    send(sockClient,queren,strlen(queren)+1,0);
    memset(filename, 0, sizeof (char) * 512); 
    memset(fpath_1, 0, sizeof (char) * 512); 
    memset(fname,0, sizeof (char) * 512); 
    memset(fflag,0, sizeof (char) * 512); 
    strcpy(fflag,abs);



    }

    printf("断开连接退出客户端");
    //////////////////
    closesocket(sockClient);
    WSACleanup();

    system("pause");
    return 0;
}

int SendFile(SOCKET sock,char filename[512])
{
    int ret,cnt,len1,lenlast;
    char sendBuf[BUFSIZE],recvBuf[BUFSIZE];
    FILE *fp;
    int totlen;
    fp=fopen(filename,"rb");
    if (NULL==fp)
    {
        printf("open file error\n");
        return -1;
    }

    fseek(fp,0,SEEK_END);
    totlen=ftell(fp);
    printf("文件%s的长度为%d字节\n",filename,totlen);

    memset(sendBuf,0,sizeof(sendBuf));
    strcpy(sendBuf,filename);

    ret=send(sock,sendBuf,strlen(sendBuf)+1,0);
    if (SOCKET_ERROR==ret)
    {
        return -2;
    }

    memset(recvBuf,0,sizeof(recvBuf));
    ret=recv(sock,recvBuf,sizeof(recvBuf),0);
    if (SOCKET_ERROR==ret|| (strcmp(sendBuf,recvBuf)!=0) )
    {
        return -3;
    } 

    printf("向服务器发送文件名成功\n");

    memset(sendBuf,0,sizeof(sendBuf));
    itoa(totlen,sendBuf,10);
    ret=send(sock,sendBuf,strlen(sendBuf)+1,0);
    if (SOCKET_ERROR==ret)
    {
        return -4;
    }

    memset(recvBuf,0,sizeof(recvBuf));
    ret=recv(sock,recvBuf,sizeof(recvBuf),0);
    if (SOCKET_ERROR==ret|| (strcmp(sendBuf,recvBuf)!=0) )
    {
        return -5;
    } 

    printf("向服务器发送文件长度成功\n");

    cnt=totlen/SIZE;
    len1=SIZE;
    if (totlen%SIZE)
    {
        lenlast=totlen-cnt*SIZE;
        cnt=cnt+1;
    }
    printf("\n\n文件总长度为%d字节,\n每次传送%d字节\n开始传输。。。。。\n",totlen,SIZE,cnt);
    int pan_10=0;
    int pan_20=0;
    int pan_40=0;
    int pan_60=0;
    int pan_80=0;

    rewind(fp);
    for(int i = 1;i<=cnt;i++){      
        if(i==cnt && (totlen%SIZE==1)){
            fread(sendBuf,lenlast,1,fp);
            ret=send(sock,sendBuf,lenlast,0);           
            if (SOCKET_ERROR==ret)
            {
                return -7;
            }           
        }
        else{
            memset(sendBuf,0,sizeof(sendBuf));
            fread(sendBuf,SIZE,1,fp);
            ret=send(sock,sendBuf,SIZE,0);
            if (SOCKET_ERROR==ret)
            {
                return -6;
            }   
            if(i*100/cnt==10 && pan_10==0)//pan_10的目的是只允许打印一次进度情况
            {
                printf("10%%");
                pan_10=1;
            }
            if(i*100/cnt==20 && pan_20==0)
            {
                printf("[■□□□□]20%%");
                printf("\r");
                pan_20=1;
            }
            if(i*100/cnt==40 && pan_40==0)
            {
                printf("[■■□□□]40%%");
                printf("\r");
                pan_40=1;
            }
            if(i*100/cnt==60 && pan_60==0)
            {
                printf("[■■■□□]60%%");
                printf("\r");
                pan_60=1;
            }
            if(i*100/cnt==80 && pan_80==0)
            {
                printf("[■■■■□]80%%");
                printf("\r");
                pan_80=1;
            }
        }

    }
    printf("[■■■■■]100%%\n");
    printf("已发送完毕\n");
    fclose(fp);
    return 0;
}

服务端代码

#include "stdio.h"
#include "winsock2.h"
#pragma comment(lib,"ws2_32.lib")
#define SERVERIP "127.0.0.1"
#define SERVERPORT 3333
#define SIZE 1024//4096
#define BUFSIZE 1024//4069

int RecvFile(SOCKET sock);
int main(void)
{
    int ret,len;
    WSADATA data;
    SOCKET sockListen,sockTx;
    struct sockaddr_in addrServer;

    ret=WSAStartup(MAKEWORD(2,2),&data);
    if (SOCKET_ERROR==ret)
    {
        return -1;
    }

    sockListen=socket(AF_INET,SOCK_STREAM,0);
    if (INVALID_SOCKET==sockListen)
    {
        WSACleanup();
        return -2;
    }

    memset(&addrServer,0,sizeof(struct sockaddr_in));
    addrServer.sin_family=AF_INET;
    addrServer.sin_addr.S_un.S_addr=inet_addr(SERVERIP);
    addrServer.sin_port=htons(SERVERPORT);

    len=sizeof(struct sockaddr);
    ret=bind(sockListen,(struct sockaddr*)&addrServer,len);
    if (SOCKET_ERROR==ret)
    {
        closesocket(sockListen);
        WSACleanup();
        return -3;
    }

    ret=listen(sockListen,1);
    if (SOCKET_ERROR==ret)
    {
        closesocket(sockListen);
        WSACleanup();
        return -4;
    }

    len=sizeof(struct sockaddr);
    sockTx=accept(sockListen,NULL,&len);
    if (INVALID_SOCKET==sockTx)
    {
        closesocket(sockListen);
        WSACleanup();
        return -5;
    }

    printf("接收到客户端的连接\n");

    RecvFile(sockTx);

    closesocket(sockListen);
    closesocket(sockTx);
    WSACleanup();
    system("pause");
    return 0;
}

int RecvFile(SOCKET sock)
{
    int ret;
    FILE *fp;
    char sendBuf[BUFSIZE],recvBuf[BUFSIZE],filename[512];

    int again=1;
    char queren[1];

    int againflag=1;

    while(again==1)
   {


    memset(recvBuf,0,sizeof(recvBuf));
    ret=recv(sock,recvBuf,sizeof(recvBuf),0);
    if (SOCKET_ERROR==ret)
    {
        return -1;
    }

    printf("成功接收客户端发来的文件名: %s\n",recvBuf);

    memset(sendBuf,0,sizeof(sendBuf));
    strcpy(sendBuf,recvBuf);
    ret=send(sock,sendBuf,strlen(sendBuf),0);
    if (SOCKET_ERROR==ret)
    {
        return -2;
    }

    printf("请输入你希望保存的文件名(带扩展名)\n");
    scanf("%s",filename);
    fp=fopen(filename,"wb");
    if (NULL==fp)
    {
        return -3;
    }

    memset(recvBuf,0,sizeof(recvBuf));
    ret=recv(sock,recvBuf,sizeof(recvBuf),0);
    if (SOCKET_ERROR==ret)
    {
        return -4;
    }

    printf("成功接收客户端发来的文件长度: %s\n",recvBuf);

    int totlen  = atoi(recvBuf); //将字符串的长度转换为数字
    int cnt=totlen/SIZE;         //计算次数
    if (totlen%SIZE)             //是否有余
    {       
        cnt=cnt+1;
    }
    int pan_10=0;                
    int pan_20=0;
    int pan_40=0;
    int pan_60=0;
    int pan_80=0;


    memset(sendBuf,0,sizeof(sendBuf));
    strcpy(sendBuf,recvBuf);
    ret=send(sock,sendBuf,strlen(sendBuf),0);
    if (SOCKET_ERROR==ret)
    {
        return -5;
    }
    int i = 1;
    for(int i = 1;i<=cnt;i++){
        ///////
        memset(sendBuf,0,sizeof(recvBuf));
        ///////
        ret=recv(sock,recvBuf,SIZE,0);
        if (SOCKET_ERROR==ret)
        {
            return -6;
        } 
        fwrite(recvBuf,ret,1,fp);
        if(i*100/cnt==10 && pan_10==0)//pan_10的目的是只允许打印一次进度情况
        {
            printf("当前接收进度已完成:10%%\n");
            pan_10=1;
        }
        if(i*100/cnt==20 && pan_20==0)
        {
            printf("[■□□□□]20%%");
            printf("\r");
            pan_20=1;
        }
        if(i*100/cnt==40 && pan_40==0)
        {
            printf("[■■□□□]40%%");
            printf("\r");
            pan_40=1;
        }
        if(i*100/cnt==60 && pan_60==0)
        {
            printf("[■■■□□]60%%");
            printf("\r");
            pan_60=1;
        }
        if(i*100/cnt==80 && pan_80==0)
        {
            printf("[■■■■□]80%%");
            printf("\r");
            pan_80=1;
        }       
    }   
    printf("[■■■■■]100%%\n");
    printf("已发送完毕,等待客户端操作\n");
    fclose(fp);
    memset(recvBuf,0,sizeof(recvBuf));
    memset(queren,0,sizeof(queren));
    ret=recv(sock,queren,sizeof(queren),0);
    if (SOCKET_ERROR==ret)
    {
        return -9;
    }
    int panduan=atoi(queren);
    if(panduan==1)
    {
      again=1;
      againflag=0;
      printf("客户端发送了新的文件\n");
     strcpy(sendBuf,"服务器收到请求");
      send(sock,sendBuf,strlen(sendBuf),0);
      memset(sendBuf,0,sizeof(sendBuf));

    }
    if(panduan==2)
    {
    again=0;
    printf("客户端已断开连接,传送结束");
    }
 }
    return 0;
}
  • 写回答

1条回答 默认 最新

  • zqbnqsdsmd 2020-08-14 07:24
    关注
    评论

报告相同问题?

悬赏问题

  • ¥15 求差集那个函数有问题,有无佬可以解决
  • ¥15 【提问】基于Invest的水源涵养
  • ¥20 微信网友居然可以通过vx号找到我绑的手机号
  • ¥15 寻一个支付宝扫码远程授权登录的软件助手app
  • ¥15 解riccati方程组
  • ¥15 display:none;样式在嵌套结构中的已设置了display样式的元素上不起作用?
  • ¥15 使用rabbitMQ 消息队列作为url源进行多线程爬取时,总有几个url没有处理的问题。
  • ¥15 Ubuntu在安装序列比对软件STAR时出现报错如何解决
  • ¥50 树莓派安卓APK系统签名
  • ¥65 汇编语言除法溢出问题