工作小记: sendto失败 errno 22 / SO_REUSEADDR SO_REUSEPROT

工作小记: sendto失败 errno 22

今天有一个udpclient发送udp数据到远端服务器的场景,由于之前都是在同一台虚拟机上进行测试,服务器和客户端都是127.0.0.1没什么问题。
网上相关问题解决方法是 sendto的sizeof问题,或者是bzero的问题。

	int sock_fd ;
    struct sockaddr_in send_addr, cli_addr;
	bzero( &send_addr, sizeof(send_addr) );

	if ((sock_fd = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP)) == -1)
    {
        perror("create socket failed!\r\n");
        exit(1);
    }

    cli_addr.sin_family = AF_INET;
	cli_addr.sin_port = htons(9693);
	cli_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
	if (bind(sock_fd, (struct sockaddr* )&cli_addr, sizeof(cli_addr)) < 0)
	{
		perror("bind");
		exit(EXIT_FAILURE);
	}

    //初始化预连接的服务端地址
    send_addr.sin_family = AF_INET;
    send_addr.sin_port = htons(9000);
    send_addr.sin_addr.s_addr = inet_addr("外网ip");
    int addr_length = sizeof(send_addr);

if( sendto(sock_fd, buff, cs_pkg.GetCachedSize(), 0, (struct sockaddr *)&send_addr, sizeof(send_addr)) < 0 )

经过测试

c s 都在内网中 都是127.0.0.1,sendto可以正常发送.
s是外网或者非本机地址后,c如果是127.0.0.1无法正常发送。
解决方法给c设置一个0 / 0.0.0.0 /或者一个具体的网卡地址
127…0.0.1和0.0.0.0区别
一文彻底明白127.0.0.1和0.0.0.0地址的区别是什么?

一台主机上只能保持最多 65535 个 TCP 连接吗?
受多种限制,fd,内存,cpu,端口号等等。协议的五元组中的协议,固定了。src 和 dest 的ip和port都可以变化,数量不止65535。

同时还有可能收到NAT的限制,NAT概念:

  • IP报文的目的IP地址是私有IP地址,网络层如何处理的?
  • NAT局域网映射公网原理简述
  • 内网和外网之间的通信(端口映射原理)

因为都是内网转到NAT做地址变换成公网。单IP做NAT支持的最大连接数问题 。协议× 源地址×源端口×目的地址×目的端口 = 2 * 1 * 2^16 * 2^32 * 2^16 = 3.68934881e+019 个连接(理想状态)最差的情况,所有的用户都访问同一个IP地址的同一协议的同一端口,则:协议×源地址×源端口×目的地址×目的端口 = 1 * 1 * 2^16 * 1 * 1 = 65536个连接(最糟糕情况)。

引申的问题,多个进程可以监听相同的端口嘛,会不会引起重复读取,惊群效应是什么
一个端口号可以同时被两个进程绑定吗? 对应的nginx不就是多个进程绑定同一个端口号嘛,可以的但是条件是fork之前绑定一个端口号,使得子父进程绑定了相同的端口号,多个进程复用socketNginx

EPOLLEXCLUSIVEepoll惊群效应怎么解决的
非要不同的进程监听相同的fd该怎么办
SO_REUSEADDR SO_REUSEPROTsocket 端口复用 SO_REUSEPORT 与 SO_REUSEADDR

抽丝剥茧–REUSEADDR 与 REUSEPORT 到底做了什么?

你可能感兴趣的:(工作杂记,网络,服务器,linux)