添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
Collectives™ on Stack Overflow

Find centralized, trusted content and collaborate around the technologies you use most.

Learn more about Collectives

Teams

Q&A for work

Connect and share knowledge within a single location that is structured and easy to search.

Learn more about Teams

I got trouble on using sendto() function in socket

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;

the recvfrom() works fine, but every time sendto() was called, the error handling print out this: sendto() failed: Invalid argument

the send program is here:

#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);
                change cliLen in the call to sendto(2) to sizeof (struct sockaddr_in) or sizeof cliaddr.  Probably the system call automatic checking is invalidating the parameter size you pass to the kernel.
– Luis Colorado
                Aug 24, 2015 at 9:17
  

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

Therefore, initialize your cliLen variable with:

socklen_t cliLen = sizeof(cliaddr);
                This did works, but I'm cruise that why: if I already know the length of the sockaddr, why bother to get the length any way?
– user2269707
                Aug 23, 2015 at 12:56
                From man recvfrom: "The returned address is        truncated  if  the  buffer provided is too small; in this case, addrlen        will return a value greater than was supplied to the call." This means addrlen indicates potential buffer overflows.
– cadaniluk
                Aug 23, 2015 at 13:02
                @reavenisadesk, not.  You don't know.  you have changed cliLen in the call to recvefrom, so you lost the value.  The system call interface to the kernel expects fixed sizes to pass to the kernel, but when returning from it you can get a different value for the size returned in the struct sockaddr_in structure, to allow you to improve storage.  If you check the structure definition, you'll find padding on the structure (not being accounted for in the returning from kernel side, but needed in the system call parameter checking)
– Luis Colorado
                Aug 24, 2015 at 9:19
                @LuisColorado yes, the cliLen was init at first, but changed each time recvfrom calls, right?
– user2269707
                Aug 24, 2015 at 9:40
        

Thanks for contributing an answer to Stack Overflow!

  • Please be sure to answer the question. Provide details and share your research!

But avoid

  • Asking for help, clarification, or responding to other answers.
  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.