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

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 树莓派与pix飞控通信
  • ¥15 自动转发微信群信息到另外一个微信群
  • ¥15 outlook无法配置成功
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题