【问题标题】:Socket programming: sendto always fails with errno 22 (EINVAL)套接字编程:sendto 总是以 errno 22 (EINVAL) 失败
【发布时间】:2011-04-29 17:43:36
【问题描述】:

我总是没有收到任何字节发送,此代码的 errno 为 22(EINVAL,无效参数)。 destination_host 设置在其他地方并且已知是有效的,所以我真的不明白发生了什么。 MAXMSGSIZE 是 1000。没有错误或警告。我正在使用-Wall -Werror -pedantic进行编译

char *data_rec;
u_int data_len;

int sockfd;
uint16_t *ns;
struct sockaddr_in address;
struct sockaddr *addr;

char *ip;

int i;
int errno;
int bytes_sent;

data_len = MAXMSGSIZE;
data_rec = malloc(sizeof(char)*MAXMSGSIZE);
ns = malloc(MAXMSGSIZE*sizeof(uint16_t));
ip = malloc(MAXMSGSIZE*sizeof(char));

data_rec = "some random test stuff";

sockfd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
if(sockfd<0) {
    printf("socket() failed\n");
}

inet_ntop(AF_INET,destination_host->h_addr,ip,MAXMSGSIZE);
memset(&address, 0, sizeof(address));
address.sin_family = AF_INET;
address.sin_port = htons(theirPort);
address.sin_addr.s_addr = (unsigned long)ip;

addr = (struct sockaddr*)&address;
bind(sockfd,addr,sizeof(address));
/*Convert the message to uint16_t*/
for(i=0; i<MAXMSGSIZE; i++) {
    ns[i] = htons(data_rec[i]);
}


/* send the message */
bytes_sent = sendto(sockfd, ns, data_len, MSG_DONTWAIT, addr, sizeof(addr));
if(bytes_sent == -1) {
    printf("Error sending: %i\n",errno);
}

【问题讨论】:

  • 您可以使用perror() 获得比errno 22 更具描述性的错误消息
  • 当 s_addr 为 INADDR_ANY 时会发生什么?如果可行,您就知道问题出在... :-)
  • 另外,您似乎声明了errno 并且从未分配给它。也许你想写extern int errno

标签: c sockets udp sendto


【解决方案1】:

您提供的地址大小有误。 addr 真的是 struct sockaddr_in,而不是 struct sockaddr

把sendto的最后一个参数改成sizeof(address)

【讨论】:

  • 奇怪的是它是如何工作的。我下面的一个示例使用了 sockaddr_in 结构的大小并且工作正常。
【解决方案2】:

inet_ntop 可能不是您想要的 - 它从 network(即有线)格式转换为 presentation 格式(即“1.2.3.4”)。试试:

address.sin_addr.s_addr = *((unsigned long *)destination_host->h_addr);

【讨论】:

  • 公平地说,nos 的回答更有可能解决您看到的错误,但我的回答解释了您的下一个问题:为什么接收者什么都看不到 :)
【解决方案3】:

你有:

bytes_sent = sendto(sockfd, ns, data_len, MSG_DONTWAIT, addr, sizeof(addr));

因为sizeof(addr) == 4(或8),所以使用sizeof(*addr)

【讨论】:

  • 必须是sizeof(address),不是吗?这就是公认的答案所说的。 sizeof(*addr) 的问题在于它是sizeof(struct sockaddr),但变量实际上是struct sockaddr_in。套接字接口非常奇特,尤其是它处理不同类型和大小地址的方式。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-05-23
  • 2011-04-25
  • 2012-11-23
  • 2015-12-26
  • 2016-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多