2015-08-23 2 views
0

я получил проблемы с использованием sendto() функции в гнездеSendTo: Недопустимый аргумент

int main(int argc, const char * argv[]) { 

    int acceptFd; 
    struct sockaddr_in servaddr, cliaddr; 
    char recieveBuf[512]; 
    char sendBuf[512]; 
    socklen_t cliLen; 

    if(-1 == (acceptFd = socket(AF_INET,SOCK_DGRAM,0))) perror("socket() failed.\n"); 
    bzero(&servaddr, sizeof(servaddr)); 
    servaddr.sin_family = AF_INET; 
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY); 
    servaddr.sin_port = htons(6789); 
    if(-1==bind(acceptFd,(struct sockaddr*)&servaddr,sizeof(servaddr))) perror("bind() failed.\n"); 


    bzero(&cliaddr, sizeof(cliaddr)); 

    while(1){ 


     if(recvfrom(acceptFd, recieveBuf, 512, 0, (struct sockaddr*) &cliaddr, &cliLen) == -1) { 
      perror("recvfrom() failed"); 
      continue; 
     } 

     strcpy(sendBuf,"recieved\n"); 
     printf("%s\n",sendBuf); 
     if(-1 == sendto(acceptFd,sendBuf, 512,0,(struct sockaddr*)&cliaddr,cliLen)){ 
      perror("sendto() failed"); 
      continue; 
     } 
    } 
} 

recvfrom() работает отлично, но каждый раз, когда sendto() была вызвана, обработка печати ошибки из этого: sendto() failed: Invalid argument

посыла программа находится здесь:

#include "test.AcceptMessage.pb.h" 
#include <netinet/in.h> 
#include <arpa/inet.h> 
#include <netdb.h> 

int main(int argc, const char * argv[]) { 



    int sendSocket; 
    struct sockaddr_in cliaddr; 
    char buf[512]; 
    if(-1 == (sendSocket = socket(AF_INET,SOCK_DGRAM,0))) perror("socket() failed.\n"); 
    bzero(&cliaddr, sizeof(cliaddr)); 
    cliaddr.sin_family = AF_INET; 
    cliaddr.sin_addr.s_addr = inet_addr("127.0.0.1"); 
    cliaddr.sin_port = htons(6789); 

    sendto(sendSocket,buf, 512,0,(
      struct sockaddr*)&cliaddr, sizeof(cliaddr)); 



    recvfrom(sendSocket,buf,512,0, nullptr, nullptr); 
    printf("%s\n",buf); 





    return 0; 
} 

Так что случилось с этим кодом?

+0

изменение cliLen в вызове ** sendto (2) ** на 'sizeof (struct sockaddr_in)' или 'sizeof cliaddr'. Вероятно, автоматическая проверка системного вызова делает недействительным размер параметра, который вы передаете ядру. –

ответ

3

От man recvfrom:

Before the call, it [addrlen] should be initialized to the size of the buffer associated with src_addr.

Поэтому инициализировать cliLen переменную:

socklen_t cliLen = sizeof(cliaddr); 
+0

Это действительно работает, но я круиз, поэтому: если я уже знаю длину sockaddr, зачем беспокоиться о том, чтобы получить длину? – reavenisadesk

+0

От 'man recvfrom':« Возвращенный адрес усечен, если предоставленный буфер слишком мал, в этом случае 'addrlen' вернет значение, большее, чем было предоставлено для вызова». Это означает, что 'addrlen' указывает на переполнение потенциальных буферов. – Downvoter

+0

большое спасибо, кажется, что я должен прочитать документ API более осторожным. – reavenisadesk

0

У вас нет никаких причин, чтобы использовать recvfrom() и sendto() вообще здесь. Это подключенный разъем. Просто используйте send() и recv().

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