添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
高大的山羊  ·  Excel 有哪些和 vlookup ...·  8 月前    · 
阳刚的键盘  ·  Simulink仿真模块 - Rate ...·  1 年前    · 
胆小的签字笔  ·  elasticsearch - ...·  1 年前    · 
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'm trying to get a program (client) to communicate with another (server) using sockets in C, but I'm constantly getting the error "Invalid Argument" from the server.

I'll try to show the pieces of code that are relevant to this issue after explaining what's happening:

When it comes to the Client, I assume that everything is working correctly: The client sends a request to server and the server receives the message correctly, but then when the server attempts to reply I get an "Invalid Argument" error.

This is the declaration of the variables used by the main function of the server:

int port = DEFAULT_PORT;
int sock;
struct sockaddr_in hostAdress, clientAdress;
socklen_t clientAdressLength;

Here I do the binding of the socket to the hostAdress:

sock = socket(PF_INET,SOCK_DGRAM,0);
memset(&hostAdress, 0, sizeof(struct sockaddr_in));
memset(&clientAdress, 0, sizeof(struct sockaddr_in));
hostAdress.sin_family = AF_INET;
hostAdress.sin_port = htons(port);
hostAdress.sin_addr.s_addr = INADDR_ANY;
bind(sock, (struct sockaddr*) &hostAdress, sizeof(hostAdress));

After a bit of code, I go into a loop receiving information, using recvfrom in this manner:

recvfrom(sock, dataBuffer, sizeof(dataBuffer), 0, (struct sockaddr*)&clientAdress, &clientAdressLength);

When the server receives the request, it identifies it and jumps to this function (this behaviour is confirmed):

handle_helloRQ(sock, clientAdress, clientAdressLength);

While I am aware that "clientAdressLength" could be obtained doing sizeof(clientAdress), somehow doing this fixed this same issue last time I had it. This function is declared as:

int handle_helloRQ(int sock, struct sockaddr_in server_addr, socklen_t server_addr_length)

In this function, the main variables are:

char buffer[512];
size_t bufferSize = sizeof(buffer);
memset(&buffer, 0, sizeof(buffer));
stshort(2, buffer);
strcat(buffer+2, "Hello World");

stshort is a simple macro that places a short int in the first 2 bytes of the buffer. This works as intended.

Once that is done, it attempts to do the following:

sendto(sock, buffer, bufferSize, 0, (struct sockaddr*)&server_addr, server_addr_length);

... And this is when things go wrong. sendto returns -1, and using perror("sendto"); I get an "Invalid Argument" error. I tried a thousand different ways of imputing the parameters, but I can not find an error. I have exhausted my other options when it comes to this kind of problems (namely, asks the teachers of my university and show the code to a few more advanced colleagues), and no one seemed to be able to find the error. As a side note, I do use

close(sock);

when the server receives the signal to be closed, but I may have had to force-close it once before it managed to reach this function.

To whoever is reading this, thank you for your time!

Are you aware that you are neither using an TCP nor an UDP socket, but an IP socket (protocol 0), so that the port number in the binding does not matter? – Steffen Ullrich Mar 14, 2014 at 20:43 @HalimQarroum It's declared as char dataBuffer[4];. The data the client sends is always a char[4]. – Elijah Mar 14, 2014 at 20:48 @HalimQarroum It is possible, albeit it is distributed among quite a few files, and would be relatively extensive to simply paste here. – Elijah Mar 14, 2014 at 21:19
sock = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP); // <-- add protocol
clientAdressLength = sizeof(clientAdress); // <-- add this
recvfrom(sock, dataBuffer, sizeof(dataBuffer), 0, (struct sockaddr*)&clientAdress, &clientAdressLength);
handle_helloRQ(sock, (struct sockaddr*)&clientAdress, clientAdressLength); // <-- pass address by pointer
close(sock);
int handle_helloRQ(int sock, struct sockaddr* recip_addr, socklen_t recip_addr_length)
    char buffer[512];
    memset(&buffer, 0, sizeof(buffer));
    stshort(2, buffer);
    strcat(buffer+2, "Hello World");
    sendto(sock, buffer, sizeof(buffer), 0, recip_addr, recip_addr_length);
                Shouldn't make any difference, as protocol 0 requests the default protocol of that protocol family and type.  For PF_INET and SOCK_DGRAM, that will be UDP.
– Chris Dodd
                Mar 15, 2014 at 1:26
                That may be true, but there were other changes I made as well. Initializing clientAdressLength each time recvfrom() is called, and passing the client address to handle_helloRQ() as sockaddr* instead of as sockaddr_in so the length returned by recvfrom() has meaning to sendto().
– Remy Lebeau
                Mar 15, 2014 at 3:24
                Thank you, @RemyLebeau , it worked. After some testing, I came to the conclusion that it was either the modification to the socket() function or the addition of the initialization to clientAdressLength.
– Elijah
                Mar 15, 2014 at 10:44
        

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.