V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
miterleo
V2EX  ›  程序员

神们,帮忙解答如何能在 UDP socket 中 bind 0 port

  •  
  •   miterleo · 2016-09-23 15:54:51 +08:00 · 2403 次点击
    这是一个创建于 2988 天前的主题,其中的信息可能已经有所发展或是发生改变。

    Mac os X 10.11.6

    执行 lsof -i udp -nP

    这种情况 "*:*" 是怎么搞出来的?

    3 条回复    2016-09-26 11:52:36 +08:00
    gino86
        1
    gino86  
       2016-09-23 23:39:49 +08:00
    *:* 这个应该是一个通配地址,第一个*表示 INADDR_ANY , 表示服务器监听本机的任意网卡,htonl(INADDR_ANY)。第二个*表示一个未知的端口,等到客户端连接的时候这个端口才得以确定
    miterleo
        2
    miterleo  
    OP
       2016-09-26 10:41:49 +08:00
    @gino86 ,谢谢,第一个*很好理解,主要是第二个,按照你的理解,未知端口,等客户端连接后才能确定,那么客户端程序如何连接这个未知端口呢?
    gino86
        3
    gino86  
       2016-09-26 11:52:36 +08:00
    @miterleo socket 程序通讯通常分几个阶段, tcp 的程序比 udp 程序稍微复杂一点, tcp server 通过 bind listen accept 三个步骤。而*:*则产生在第一个和第二个步骤,即 bind 和 listen 阶段,第一个*产生于 bind 函数,而第二个*则产生于 listen 函数。对于服务器,第二个*实际上是 0 端口,(在 unix 网络编程卷 1 )中看到。而在 udp 程序中,通过测试(测试环境为 mac osx 10.11.6 ),一旦通过 socket 函数创建套接字后,这个通配地址就已经生成。

    测试代码:
    #include <stdio.h>
    #include <stdlib.h>
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <string.h>
    #include <errno.h>
    #include <netinet/in.h>
    #include <unistd.h>
    #include <arpa/inet.h>

    int main( int argc, char **argv )
    {
    int sockfd;
    struct sockaddr_in servaddr;

    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0))<0 ) {
    fprintf( stderr, "socket:%s\n", strerror(errno));
    exit(EXIT_FAILURE);
    }

    int nread;
    char buf[BUFSIZ];
    while((nread = read(0, buf, BUFSIZ))>0)
    {
    }
    return 0;
    }
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1374 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 22ms · UTC 17:39 · PVG 01:39 · LAX 09:39 · JFK 12:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.