linux udp 多网卡 发送大数据包 获取修改缓冲区大小示例
经常使用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;
}