【问题标题】:C sockaddr function call for sendto?C sockaddr函数调用sendto?
【发布时间】:2017-08-25 21:08:22
【问题描述】:

我目前正在为学校作业设置 UDP 套接字,但我不知道如何正确地将 sockaddr 作为参数发送到函数中。 SendData 的输入参数的定义方式与它们在 sendto 函数中的定义方式相同。

void SendData(int fileDescriptor, const struct sockaddr_in *destAddrUdp, unsigned char buffer[MAXMSG])
{
  /* crc */
  int strlength = strlen(buffer);
  unsigned char SCRC = CRC(buffer, strlength-1);
  buffer[strlength-1] = SCRC;
  buffer[strlength] = '\0'; 
  /* send */
  if (sendto(fileDescriptor, buffer, strlen(buffer), 0, (struct sockaddr*) &destAddrUdp,sizeof(destAddrUdp)) < 0) {
    fprintf(stderr, "Could not send data\n");
  }
} `

当从 main 调用下面的代码时,它可以工作,但是当它从 SendData 调用时,sendto 的返回值为 -1。

if (sendto(fileDescriptor, buffer, strlen(buffer), 0, (struct sockaddr*) &destAddrUdp,sizeof(destAddrUdp)) < 0) {
    fprintf(stderr, "Could not send data\n");
  }

如果程序已编译,我会收到 警告:从不兼容的指针类型传递“recvfrom”的参数 5。 在 SendData 中的 sendto 函数调用上。 我的主程序中对 SendData 的函数调用是:SendData(sockfd, (struct sockaddr *) &amp;destAddrUdp, buffer);

相关的主程序:

unsigned char SCRC;
  unsigned char strlength;
  unsigned char buffer[MAXMSG-5];
  unsigned char header[MAXMSG];
  struct rtp_struct *sendstruct; 
  /* option 2 */
  struct sockaddr_in destAddrUdp;
  int sockfd; 
  char dstHost[15]; 
  printf("input host IP:\n>");
  fgets(dstHost, 15, stdin);

  /* Create socket */ 
  if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) 
    fprintf(stderr, "Can't create UDP socket\n");

  /* set configurations */
  memset (&destAddrUdp, 0, sizeof(destAddrUdp));  //set zero
  destAddrUdp.sin_family = AF_INET; //internet use
  destAddrUdp.sin_addr.s_addr = inet_addr(dstHost); //set so anyone can connect
  destAddrUdp.sin_port = htons(dstUdpPort); //set the port to use

  /* Generate CRC table */
  GenerateCRCTable();

/* get string and send */
while(1) {
    printf("\n>");
    fgets(buffer, MAXMSG, stdin);
    if(strncmp(buffer,"quit\n",MAXMSG) != 0){ //if read string == quit, see else
      strlength = strlen(buffer);
      SCRC = CRC(buffer, strlength-1);
      buffer[strlength-1] = SCRC;
      buffer[strlength] = '\0';

      SendData(sockfd, (struct sockaddr *) &destAddrUdp, buffer);
      /*if (sendto(sockfd, buffer, strlength, 0, (struct sockaddr *) &destAddrUdp,sizeof(destAddrUdp)) < 0){
        fprintf(stderr, "Could not send data\n");}*/
    }  
    else {   
      close(sockfd); 
      exit(EXIT_SUCCESS);
    }
  }
}

【问题讨论】:

  • 快速标准备注:请注意,现在是 2017 年,您仍在编写仅支持旧 IP 地址的软件。最好养成在您的软件中同时支持sockaddr_in6sockaddr_in(用于旧IP)的习惯。 (一旦你弄清楚了你当前的问题。)
  • 为什么这个(struct sockaddr *) &amp;destAddrUdp 会转换成main()

标签: c linux sockets pointers sockaddr-in


【解决方案1】:

在您的SendData 函数中,参数destAddrUdp 的类型为const struct sockaddr_in *。然后当您拨打电话时:

sendto(fileDescriptor, buffer, strlen(buffer), 0, 
       (struct sockaddr*) &destAddrUdp, sizeof(destAddrUdp)

表达式&amp;destAddrUdp 的类型为const struct sockaddr_in **,因此指针类型不兼容。此外,sizeof(destAddrUdp) 返回的是指针的大小,而不是结构的大小。

您未能说明SendDatamain 中不同类型的destAddrUdp。对sendto 的正确调用是:

sendto(fileDescriptor, buffer, strlen(buffer), 0, 
       (struct sockaddr*) destAddrUdp, sizeof(*destAddrUdp)

【讨论】:

  • 不兼容的不仅仅是指针类型——这可以通过适当的强制转换来解决。值本身是错误的,因为您没有传递 sockaddr 结构的地址,而是传递指向 sockaddr 结构的指针的地址...
【解决方案2】:

问题在于sizeof(destAddrUdp)(struct sockaddr*) &amp;destAddrUdp

在您的 main 中,destAddrUdpstruct sockaddr_in,但在您的函数中,它是 sockaddr_in*,因此您不能平等地使用它们。首先,你的函数中的sizeof(destAddrUdp) 会给你一个指针的大小,其次,你的函数中的&amp;destAddrUdp 会给你一个destAddrUdp**。那不是你想要的。

试试sendto(fileDescriptor, buffer, strlen(buffer), 0, (struct sockaddr*) destAddrUdp,sizeof(*destAddrUdp))

【讨论】:

    猜你喜欢
    • 2014-01-17
    • 1970-01-01
    • 2012-07-28
    • 2015-07-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多