2010-10-24 4 views
4

Я всегда получаю никаких байтов, отправленных с ошибкой 22 (EINVAL, Invalid Argument) с помощью этого кода. destination_host установлен в другом месте и известен как действительный, поэтому я действительно не вижу, что происходит. MAXMSGSIZE - 1000. Нет ошибок или предупреждений. Я компиляция с -Wall -Werror -pedanticПрограммирование сокетов: sendto всегда терпит неудачу с errno 22 (EINVAL)

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); 
} 
+1

Вы можете использовать 'perror()' для получения более описательного сообщения об ошибке, чем 'errno 22' –

+0

Что происходит, когда s_addr is INADDR_ANY? Если это сработает, вы знаете, проблема в том, что ... :-) – 2010-10-24 01:35:49

+0

Кроме того, кажется, что вы объявляете 'errno' и никогда не назначаете его. Может быть, вы хотели написать 'extern int errno'? – vadipp

ответ

11

Вы даете неправильный размер для адреса. addr действительно struct sockaddr_in, а не struct sockaddr.

Изменить последний параметр SendTo для sizeof(address)

+0

Странно, как это сработало. В следующем примере я использовал размер структуры sockaddr_in и работал нормально. –

5

inet_ntop, вероятно, не то, что вы хотите - это преобразование из сети (т.е. проволоки) формата в формат представления (т.е. «1.2.3.4»). Попробуйте:

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

Справедливости ради, ответ nos чаще всего исправляет ошибку, которую вы видите, но мой ответ объясняет вашу следующую проблему: почему получатель ничего не видит :) – SimonJ

+0

Спасибо. Я бы тоже принял этот ответ, если бы мог: P –

-1

У вас есть:

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

Поскольку sizeof(addr) == 4 (или 8), используйте sizeof(*addr).

+0

Он должен быть 'sizeof (address)', не так ли? И вот что говорит принятый ответ. Проблема с 'sizeof (* addr)' заключается в том, что это 'sizeof (struct sockaddr)', но переменная на самом деле является 'struct sockaddr_in'. Интерфейс сокетов довольно странный, особенно способ обработки различных типов и размеров адресов. –

Смежные вопросы