2015-08-23 220 views
0

我在插座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()叫,錯誤處理打印出這一點: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

在調用** sendto(2)**到'sizeof(struct sockaddr_in)'或'sizeof cliaddr'的調用中更改cliLen。系統調用自動檢查可能會使傳遞給內核的參數大小無效。 –

回答

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().