udp套接字sendto隐式绑定
udp socket sendto implicit bind
我在这里查看udp客户端示例:http://www.linuxhowtos.org/data/6/client_udp.c
代码段:
/* UDP client in the internet domain */
struct sockaddr_in server, from;
//...snipped
sock= socket(AF_INET, SOCK_DGRAM, 0);
if (sock < 0) error("socket");
server.sin_family = AF_INET;
hp = gethostbyname(argv[1]);
if (hp==0) error("Unknown host");
bcopy((char *)hp->h_addr,
(char *)&server.sin_addr,
hp->h_length);
server.sin_port = htons(atoi(argv[2]));
length=sizeof(struct sockaddr_in);
//... snipped
n=sendto(sock,buffer,
strlen(buffer),0,(const struct sockaddr *)&server,length);
if (n < 0) error("Sendto");
n = recvfrom(sock,buffer,256,0,(struct sockaddr *)&from, &length);
if (n < 0) error("recvfrom");
//... snipped
我正在努力了解它是如何知道从哪里接收信息的。我知道当调用sendto
时,会选择一个可用端口,该端口嵌入udp消息中,服务器应用程序可以读取并回复它。客户端代码如何知道在该端口上接收消息?
这个答案:https://stackoverflow.com/a/48245273/2748602指示在调用sendto
函数时存在某种隐式绑定。它是如何工作的?它实际上是一个与随机可用端口号的绑定吗?该端口号是永久的,就像我调用了bind
或其他什么一样?似乎有一些永恒的方面。只是对更多的细节感兴趣。
如果套接字未绑定,则是一个隐式绑定,因为所有数据包都必须同时携带一个源端口。因此,API假设,如果您事先对端口不够关心,无法绑定套接字,则它可以将套接字绑定到随机端口。不幸的是,虽然我不知道sendto
的实现细节,但我可以提供一些官方文档。
对于Linux,来自udp手册页:
创建UDP套接字时,其本地和远程地址为未指明。可以使用sendto(2)或sendmsg(2),并将有效的目标地址作为参数。什么时候connect(2)在默认目的地套接字上调用地址已设置,数据报现在可以使用发送(2)或写入(2)发送而不指定目的地地址。仍然有可能通过将地址传递给sendto(2)发送到其他目的地,或sendmsg(2)为了接收数据包,套接字可以绑定到本地地址首先使用bind(2)*否则,套接字层将自动分配一个超出定义范围的可用本地端口通过/proc/sys/net/ipv4/ip_local_port_range并将套接字绑定到INADDR_ANY。
对于Windows,Winsock 2的sendto:的文档片段
如果套接字未绑定,则会将唯一值分配给本地关联,然后套接字被标记为绑定。如果套接字已连接,getsockname函数可用于确定与套接字相关联的本地IP地址和端口。
。。。当调用sendto函数时,存在一种隐式绑定。它是如何工作的?它实际上是一个具有随机可用端口号的绑定吗?它是永久的,就像我调用了绑定或其他什么一样?
man ip(7)
:
ip_local_port_range (since Linux 2.2)
This file contains two integers that define the default local
port range allocated to sockets that are not explicitly bound
to a port number—that is, the range used for ephemeral ports.
An ephemeral port is allocated to a socket in the following
circumstances:
* the port number in a socket address is specified as 0 when calling bind(2);
* listen(2) is called on a stream socket that was not previously bound;
* connect(2) was called on a socket that was not previously bound;
* sendto(2) is called on a datagram socket that was not previously bound.
- 我想将一个对T类型的非常量左值引用绑定到一个T类型的临时值
- 在基于范围的for循环中使用结构化绑定声明
- 使用 LuaBridge 将 LuaJIT 绑定到C++会导致"PANIC: unprotected error"
- 尝试通过OCI例程从Oracle获取blob数据,但出现错误:ORA-01008:并非所有变量都绑定
- 在使用GPU支持编译Tensorflow时,会遇到CUDA_TOOLKIT_PATH未绑定变量
- 视觉studo 2019中的漫画和静态/动态绑定
- 将自由函数绑定为类成员函数
- 将常量指针引用绑定到非常量指针
- 在派生类中绑定非静态模板化成员函数
- 绑定派生类方法C++从实例范围之外的分隔 std::function 变量调用
- 在 openGL 中多次绑定缓冲区
- 定义有趣的宏和正则表达式在Z3 C++绑定
- 使用结构化绑定'Reflection'
- 为什么 std::绑定错误参数可以成功?
- 如何绑定 C++ gRPC 客户端的网络接口
- 在 openmp 中,omp_get_thread_num是否绑定到物理线程?
- C++绑定(已弃用)
- 运行时错误:引用绑定到类型为"int"的空指针
- udp套接字sendto隐式绑定
- C++套接字编程:sendto()和recvfrom()错误代码10038和in 'server'绑定失败,10038