C语言 获取套接字的随机端口

rvpgvaaj  于 2023-10-16  发布在  其他
关注(0)|答案(2)|浏览(91)

我知道这个问题已经被问过了,但我似乎是某种“特殊”,因为我的代码不工作。指令是“绑定端口0并使用getsockname获取端口”。我做错了什么。。

struct sockaddr_in sa;

sa.sin_port=htons(0);
sa.sin_addr.s_addr=htonl(INADDR_ANY);
sa.sin_family=AF_INET;

int sock;
sock = socket(AF_INET, SOCK_STREAM, 0);

struct sockaddr *serverptr = (struct sockaddr*)&sa;
bind(sock, serverptr,sizeof(sa));
socklen_t s=sizeof(sa);
int g=getsockname(sock,serverptr,&s);

g总是打印为0。
编辑:这是如此简单,只是sa.sin_port愚蠢的问题。

eit6fx6z

eit6fx6z1#

大多数Berkley Socket API函数使用非常简单的约定:返回的结果是操作成功指示。所以,零表示正常,负表示错误。为了安全起见,您必须始终检查它,并且您的代码对于socket()bind()getsockname()调用缺少此验证:

...
int sock = socket(AF_INET, SOCK_STREAM, 0);
if (sock < 0) {
    // log the error, etc
    return;
}
int res = bind(sock, serverptr, sizeof(sa));
if (res < 0) {
    // log the error, etc
    close(sock);
    return;
}
socklen_t s = sizeof(sa);
res = getsockname(sock, serverptr, &s);
if (res < 0) {
    // log the error, etc
    close(sock);
    return;
}
...
k2arahey

k2arahey2#

#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

int
main (int argc, char** argv)
{
  int sock;
  struct sockaddr_in name;
  char *addr;

  if(argc<2) {
     addr="0.0.0.0";
  } else {
     addr=argv[1];
  }
  /* Create the socket. */
  sock = socket (PF_INET, SOCK_STREAM, 0);
  if (sock < 0)
    {
      perror ("socket");
      exit (EXIT_FAILURE);
    }

  /* Give the socket a name. */
  name.sin_family = AF_INET;
  name.sin_port = htons (0);
  name.sin_addr.s_addr = inet_addr(addr);
  if (bind (sock, (struct sockaddr *) &name, sizeof (name)) < 0)
    {
      perror ("bind");
      exit (EXIT_FAILURE);
    }

  int len = sizeof(name);
  int sn = getsockname(sock, (struct sockaddr *)&name, &len);
  printf("Port is %d\n",ntohs(name.sin_port));
  return sock;
}

编译:gcc getport. c-o getport
用法:./getport [address]

Ouput:
./getport
Port is 31725
./getport 127.0.0.1
Port is 32064
./getport 1.2.3.4
bind: Cannot assign requested address

相关问题