簡體   English   中英

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)時,將設置默認目標地址,並且現在可以使用send(2)或write(2)發送數據報,而無需指定目標地址。 通過將地址傳遞給sendto(2)或sendmsg(2),仍然可以發送到其他目標。 為了接收數據包,可以先使用bind(2)將套接字綁定到本地地址。 *否則,套接字層將自動分配超出/ proc / sys / net / ipv4 / ip_local_port_range定義的范圍的空閑本地端口,並將套接字綁定到INADDR_ANY

對於Windows,請參閱Winsock 2 sendto文檔中的摘錄:

如果套接字未綁定,則系統會將唯一值分配給本地關聯,然后將套接字標記為bound 如果已連接套接字,則可以使用getsockname函數來確定與套接字關聯的本地IP地址和端口。

...調用sendto函數時,存在一種隱式綁定。 它是如何工作的? 實際上,它是一個具有隨機可用端口號的綁定,該端口號是否永久不變,就像我曾叫過bind一樣?

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.

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM