经常使用UDP发送数据,但一般都是小包,没有太关注过发送大包的问题。突然要发个大包,c++ udp send big packet。
就tcpdump wireshark抓包看了一下。
结果在tcpdump中,出现了这个东西。
UDP, bad length 5455 > 1472
看来UDP包长度超过MTU了。应该是分片了,但分片就分片,只要网络可靠,应该都没什么问题。

另外就是怕UDP的接收或者发送缓冲区不够了。

udp setsockopt sendbuf example

还有多网卡的问题。直接指定网卡,这个要用到struct ifreq.这是linux下的用法。
windows好像没有这个SO_BINDTODEVICE选项,不过可以使用静态路由的方式。可以参考这个链接:
多网卡指定网卡进行UDP通信(添加静态路由解决双网卡问题 )全记录
最后代码如下:

注意 struct ifreq 头文件如下: struct ifreq header file

#include <sys/ioctl.h>
#include <net/if.h>

int cudp::udp_send(string ip, int port, string data)
{
    printf("udp_send ip=%s,port=%d\n",ip.c_str(),port);
    int m_nsockfd;
    if ((m_nsockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
    {
        printf("udp_send error.\n");
        return -1;
    }
    struct ifreq ifr;
    memset(&ifr, 0x00, sizeof(ifr));
    strncpy(ifr.ifr_name, "eth0", 4);
    setsockopt(m_nsockfd, SOL_SOCKET, SO_BINDTODEVICE, (char *)&ifr, sizeof(ifr));

    int addrlen = sizeof(sockaddr_in);
    struct sockaddr_in addr;
    bzero(&addr, sizeof(struct sockaddr_in));    
    addr.sin_family = AF_INET;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr(ip.c_str());
    int sendbuff;
    socklen_t optlen;
    int res = 0;

    // Get buffer size
    optlen = sizeof(sendbuff);
    res = getsockopt(m_nsockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, &optlen);

    if(res == -1)
        printf("Error getsockopt one");
    else
        printf("send buffer size = %d\n", sendbuff);

    sendbuff = 50*1024;

    printf("sets the send buffer to %d\n", sendbuff);
    res = setsockopt(m_nsockfd, SOL_SOCKET, SO_SNDBUF, &sendbuff, sizeof(sendbuff));

    if(res == -1)
        printf("Error setsockopt");
        
    int ret = sendto(m_nsockfd, data.data(), data.length(), 0, (struct sockaddr *)&addr, addrlen);
    printf("sendto ret = %d\n", ret);
    return ret;
}
本文链接地址:https://const.net.cn/267.html

标签: linux, udp, socket

添加新评论