Horbyn4zZ 2018-10-26 15:02 采纳率: 100%
浏览 1976

WINDOWS C SOCKET编程 recv()接收不到数据?

我的代码逻辑(C语言实现断点续传的demo)大概是

服务器将文件分片,每次向客户端只发送一个分片,只有等客户端返回应答才继续发送接下来的分片

现在我遇到的问题是

客户端发送的应答,能发送到套接字的输出缓冲区,可是,服务器这边却recv()不到这个应答

我想不到是什么原因,help me

代码

 //服务器

    //保存上次下载标识  
    int id;  
    //从tfp指向的文件即Temp.txt读取内容,默认为0,即从第一个片开始  
    id = fgetc(tfp);  
    int idsize = sizeof(id);  

    //需要一个接收客户端应答的缓冲区  
    char buffer[BUF_SIZE] = { 0 };  
    char *bp = buffer;  
    printf("Server will send files to the client\n\n\n\n");  
    int recvLen = 0,sendLen=0;  
    for ( i = 0; i < PIECE; i++)  
    {  
        //记录当前下载到哪一个片,保存到Temp.txt  
        fputc(i, tfp);  
        printf("the %d of for circle\n", i);  
        //上次下载到哪里,这一次便从那里开始  
        if (sli[i].grade == id) {  
            //每次发送一个分片  
            printf("\tserver will send the %d piece of the file\n",i+1);  
            if ((sendLen = send(sock, dp[i], tsize, 0)) < 0)  
            {  
                printf("\tsend a mess to client had failed, and the successful bytes is:%d\n", sendLen);  
            }  
            else  
            {  
                printf("\tsend a mess to client was succeeded, and the successful bytes is:%d\n", sendLen);  
            }  
            /* 
             *服务器每发送一个分片,必须根据客户端的应答进行判断 
              *1、客户端应答已收到(用字符'f'表示)——继续发送剩下的分片,并且显示传输进度 
              *2、客户端应答未收到(用字符'n'表示)——保存当前下载标识,结束传输 
            */  

            //recv()的作用是阻塞,因为要接收客户端的应答  
            printf("\t\twait to receive respond from client\n");  
            if ((recvLen = recv(sock, buffer, nCount, 0)) > 0) {  
                printf("\tthe num to recv respond from client is %d,and the nCount is %d\n", i + 1, recvLen);  
            }  
            else  
            {  
                printf("receive respond failed! return:%d\n",recvLen);  
            }  
            //应答超时设置为6s,表示经过了6s以后,若客户端还没有应答,就不再等待该应答  
            //Sleep(6000);  
            if (*bp=='f')  
            {  
                //若客户端已收到应答  
                //表示已发送完毕一个分片,下载标识+1,并且打印传输进度  
                printf("Server gets the respond from client\n");  
                printf("\tthe rate of transported procession now is:%d%%\n", i * 100 / PIECE);  
                if (i % 10 == 0)  
                    printf("\n");  
                id++;  
            }  
            else if(*bp=='n')  
            {  
                //若客户端收不到应答  
                //也就是当前分片也发送失败,即当前下载标识不需要自增1——记录当前下载标识  
                printf("Server misses the respond from client\n");  
                fputc(i, tfp);  
                break;  
            }  
            else  
            {  
                printf("nothing\n");  
            }  
            if (id == PIECE)  
                printf("\n传输完成!\n");  
            printf("\n");  
        }  
    }  

客户端代码

 //客户端

  /*
     *接收缓冲区是连续接受数据的
     *  每次接收一个片就返回应答
     *  同时写进文件(buffer->rfp)
    */

    char buffer[BUF_SIZE] = { 0 };
    //客户端用指向字符常量的指针来表示应答
    char idNarr[2] = "n";
    char idFarr[2] = "f";
    const char *ip = idNarr;
    //该应答标识的实际长度
    int len = sizeof(ip) / sizeof(const char *);
    //实际接收字节
    int rLen = 0, i,nCount,fwLen;
    printf("\n\n\n\n");
    for (i = 0; i < PIECE; i++)
    {
        printf("the %d of for circle\n",i);
        rLen = recv(clntSock, buffer, BUF_SIZE, 0);
        buffer[rLen] = '\0';
        //检验是否从套接字的输入缓冲区接收到数据
        printf("receive from server is %s,the length is %d\n",buffer,rLen);
        printf("ip point to the string is:%s\n",ip);
        //接收到数据就把应答标识标志为f
        ip =idFarr;
        printf("ip point to the string is:%s\n",ip);
        //发送应答标识,并检查是否发送成功
        if ((nCount= send(clntSock, ip, len, 0))<0)
        {
            printf("send a mess to server had failed, and the successful bytes is:%d", nCount);
        }
        else
        {
            printf("send a mess to server was succeeded, and the successful bytes is:%d\n", nCount);
        }
        ip = idNarr;
        //将接收到的数据写入本地文件,并检查是否写入成功
        if((fwLen = fwrite(buffer, 1, rLen, fp)) > 0) {
            printf("\tto write something into file of %d,and the nCount is %d\n", i + 1, rLen);
        }
        else
        {
            printf("fwrite failed!\n");
        }
    }
  • 写回答

3条回答 默认 最新

  • devmiao 2018-10-26 16:40
    关注
    评论

报告相同问题?

悬赏问题

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