关于udp socket recvfrom函数的一个易错问题: 如果应用程序指定的接收长度不够怎么办?

972 篇文章 329 订阅
148 篇文章 34 订阅

        我们来看这样一个问题, 在udp socket编程中, sendto连续三次发送10个字节的数据“0123456789”, 此时对端连续三次调用recvfrom函数来接收, 每次接收2个字节, 请问是接收到“01” “23” “45” 还是 “01” “01” “01” ? 我们先来看看程序:

       服务端:

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main()
{
    struct sockaddr_in srvAddr;
    bzero(&srvAddr,sizeof(srvAddr));
    srvAddr.sin_family = AF_INET;
    srvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
    srvAddr.sin_port = htons(8888);
    int srvAddrLen = sizeof(srvAddr);

    int iSock = socket(AF_INET, SOCK_DGRAM, 0);  // udp
    bind(iSock, (struct sockaddr *)&srvAddr, sizeof(srvAddr));

    while(1)
    {
		getchar(); 
		char szBuf[3] = {0};
        int iRet = recvfrom(iSock, szBuf, sizeof(szBuf) - 1, 0, (struct sockaddr *)&srvAddr, (socklen_t*)&srvAddrLen);
        printf("msg from client [%s], iRet is %d\n", szBuf, iRet);
    }

    close(iSock);
    return 0;
}

       客户端为:

 

 

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>

int main()
{
    struct sockaddr_in srvAddr;
    bzero(&srvAddr, sizeof(srvAddr));
    srvAddr.sin_family = AF_INET;
    srvAddr.sin_addr.s_addr = inet_addr("127.0.0.1");
    srvAddr.sin_port = htons(8888);

    int iSock = socket(AF_INET, SOCK_DGRAM, 0); // udp
    while(1)
    {
		printf("press enter to send data\n");
		getchar();
		char szBuf[128] = {0};
        snprintf(szBuf, sizeof(szBuf), "0123456789");
		printf("send size is %d\n", strlen(szBuf));
        sendto(iSock, szBuf, strlen(szBuf), 0, (struct sockaddr *)&srvAddr, sizeof(srvAddr));
    }

	close(iSock);
    return 0;
}

      先启动服务端, 再启动客户端。

 

      客户端连续三次给服务端发送数据后, 客户端结果为:

 

xxxxxx:~/network> ./client
press enter to send data

send size is 10
press enter to send data

send size is 10
press enter to send data

send size is 10
press enter to send data

       然后服务端三次接收, 结果为:

 

 

xxxxxx:~/network> ./server

msg from client [01], iRet is 2

msg from client [01], iRet is 2

msg from client [01], iRet is 2

       咦, “23456789”跑哪里去了? 

 

       这就是涉及到udp的数据报传输方式了, 发几次就需要几次来收, 如果收包长度不过, 多的会被丢弃, 而不会在下次recvfrom的时候取到。

       所以, 在使用udp socket编程的时候, 务必注意这点, buffer太小, 容易导致概率性问题(长包接收不完整而出错, 注意, 此时recvfrom函数并不会返回一个错误的值)。

 

 

 

  • 5
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 8
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值