c - 当我进行UDP广播后,我如何知道我在哪个端口上广播?

标签 c linux sockets udp

我有一个必须使用 UDP 的 Linux C 应用程序。服务器广播“发现数据包”,然后监听任何连接的客户端以类似的回声进行应答。通过使用端口,客户端和服务器可以使用不同的端口进行通信。

以下是服务器广播其发现数据包的方式:

int main() {
  puts("starting");
  int sock;
  int yes = 1;
  struct sockaddr_in broadcast_addr;
  int addr_len;
  int count;
  int ret;
  fd_set readfd;
  char buffer[1024];
  char outbound_buffer[63];
  int i;

  sock = socket(AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) {
    perror("sock error");
    return -1;
  }
  ret = setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char*)&yes, sizeof(yes));
  if (ret == -1) {
    perror("setsockopt error");
    return 0;
  }
  memset(outbound_buffer,0,sizeof(outbound_buffer));

  addr_len = sizeof(struct sockaddr_in);

  memset((void*)&broadcast_addr, 0, addr_len);
  broadcast_addr.sin_family = AF_INET;
  broadcast_addr.sin_addr.s_addr = htonl(INADDR_BROADCAST);
  broadcast_addr.sin_port = htons(PORT);

  outbound_buffer[0] = 0xEF;
  outbound_buffer[1] = 0xFE;
  outbound_buffer[2] = 0x02;

    ret = sendto(sock, outbound_buffer, 63, 0, (struct sockaddr*) &broadcast_addr, addr_len);

这很好用;客户端收到发现并获取服务器的IP和端口:

int main() {

  stoplink = 0;
  stopData = 0;
  int addr_len;
  int count;
  int ret;
  fd_set readfd;
  char buffer[1024];
  sock = socket(AF_INET, SOCK_DGRAM, 0);
  if (sock < 0) {
    perror("sock error\n");
    return -1;
  }
  addr_len = sizeof(struct sockaddr_in);
  memset((void*)&server_addr, 0, addr_len);
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = htons(INADDR_ANY);
  server_addr.sin_port = htons(PORT);

  ret = bind(sock, (struct sockaddr*)&server_addr, addr_len);
  if (ret < 0) {
    perror("bind error\n");
    return -1;
  }
  while (1) {

  puts("Initialized; await discovery");

    FD_ZERO(&readfd);
    FD_SET(sock, &readfd);

    ret = select(sock+1, &readfd, NULL, NULL, 0);
    if (ret > 0) {
      if (FD_ISSET(sock, &readfd)) {
        count = recvfrom(sock, buffer, 1024, 0, (struct sockaddr*)&client_addr, &addr_len);
        if((buffer[0] & 0xFF) == 0xEF && (buffer[1] & 0xFF) == 0xFE) {
      fprintf(stderr,"discovery packet detected\n"); 
          cmdport = ntohs(client_addr.sin_port);
          printf("\nClient connection information:\n\t IP: %s, Port: %d\n", 
            inet_ntoa(client_addr.sin_addr), ntohs(client_addr.sin_port));

       count = sendto(sock, buffer, strlen(buffer), 0, (struct sockaddr*)&client_addr,
         sizeof(client_addr));
        }
      }
    }

  puts("Now starting command processing loop");

这也可以正常工作...但它将回复发送到广播来自的服务器上的端口 - 这是由服务器自动随机选择的;那么我如何知道服务器端监听哪个端口来接收客户端的回复呢?

最佳答案

服务器不需要做任何额外的事情。一旦发送数据包,服务器端的端口就被设置。

例如,如果客户端看到服务器消息来自端口 34567,则服务器套接字正在使用端口 34567。然后,在端口 34567 发送到服务器的任何消息都可以由同一服务器套接字读取。

因此服务器只需调用 recvfrom 即可获取客户端的响应。

关于c - 当我进行UDP广播后,我如何知道我在哪个端口上广播?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59698398/

相关文章:

c - 当我在 select 中使用 read() 时我有一个问题

linux - 尝试在 CDH-5.4.2 中安装 hbase

c - sendmmsg()返回-1,没有可用的缓冲区空间,为什么memset解决这个问题?

c# - 从 TcpClient 获取源 IP

c++ - 预处理器输出的数字指令是什么?

遍历目录时的 C 编程段错误

c - Windows编程中的Console是什么意思?

linux - 如何使用 imagemagick convert 合并 5 个以上的 PDF?

c - 逗号分隔的表达式作为 for 循环中的条件如何工作?

c - C中通过socket接收和发送数据