Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game. |
Notices |
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
Are you new to LinuxQuestions.org? Visit the following links:
Site Howto |
Site FAQ |
Sitemap |
Register Now
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
|
|
11-01-2006, 01:31 PM
|
#1
|
LQ Newbie
Registered: Aug 2006
Location: Ukraine
Distribution: Debian Etch
Posts: 15
Rep:
|
sendto: invalid argument
I know this is very basic question, but i really need a little help here :\
In my program i have function mysend(), which is a wrapper to sendto() call:
Code:
void mysend(const char *sendstring, const struct sockaddr_in *addr){
int sendstringlen = strlen(sendstring);
if(sendto(main_socket, sendstring, sendstringlen, 0, addr, sizeof(struct sockaddr_in)) == -1){
perror("sendto");
}
}
The main_socket is UDP socket.
I also have a global struct sockaddr_in current, which represents address of the machine i currently communicate with. This stucture is already filled by the recvfrom(...) call.
But when i call mysend("hello",¤t); it prints error: sendto: invalid argument.
I just can't find where the mistake is... :\
P.S. my platform is Gnu/Linux
|
|
|
11-01-2006, 01:44 PM
|
#2
|
Senior Member
Registered: Jan 2005
Location: Canada
Distribution: ubuntu
Posts: 2,539
Rep:
|
do all your parameters' type match the required:
Code:
int sendto(int, const char *, size_t, int, struct sockaddr *, size_t);
|
|
|
11-01-2006, 01:59 PM
|
#3
|
Moderator
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696
|
Code:
if(sendto(main_socket, sendstring, sendstringlen, 0, (struct sockaddr *)addr, sizeof(struct
struct sockaddr and struct sockaddr_in are compatibile, so you can cast one to another, but they're still different types, that's why casting is required.
|
|
|
11-01-2006, 05:31 PM
|
#4
|
LQ Newbie
Registered: Aug 2006
Location: Ukraine
Distribution: Debian Etch
Posts: 15
Original Poster
Rep:
|
Hmm, added (struct sockaddr *), but it still returns an error
Strange behavior, isn't it?
Anyway, thanks for help
|
|
|
11-01-2006, 05:34 PM
|
#5
|
Senior Member
Registered: Jan 2005
Location: Canada
Distribution: ubuntu
Posts: 2,539
Rep:
|
then one of the other parameters is wrong. the first parameter says its supposed to be 'int', is main_socket of type 'int'??
|
|
|
11-01-2006, 05:43 PM
|
#6
|
LQ Newbie
Registered: Aug 2006
Location: Ukraine
Distribution: Debian Etch
Posts: 15
Original Poster
Rep:
|
Unfortunately it is int
Last edited by Yury; 11-01-2006 at 05:45 PM.
|
|
|
11-01-2006, 08:23 PM
|
#7
|
Senior Member
Registered: Jan 2005
Location: Canada
Distribution: ubuntu
Posts: 2,539
Rep:
|
can you change sendstring to &sendstring does that help? (?)
Last edited by nadroj; 11-01-2006 at 08:37 PM.
|
|
|
11-01-2006, 08:24 PM
|
#8
|
Member
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600
Rep:
|
can you post how you're filling up the sockaddr_in struct?
|
|
|
11-02-2006, 04:34 PM
|
#9
|
Moderator
Registered: Feb 2002
Location: Grenoble
Distribution: Debian
Posts: 9,696
|
I have made a short test. The code below compiles fine:
Code:
#include <string.h>
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
int main_socket = -1;
void mysend(const char *sendstring, const struct sockaddr_in *addr){
int sendstringlen = strlen(sendstring);
if(sendto(main_socket, sendstring, sendstringlen, 0, (struct sockaddr *)add
perror("sendto");
}
}
int main(int argc, char **argv)
{
struct sockaddr_in sock;
mysend("blah", &sock);
return 0;
}
|
|
|
11-02-2006, 05:47 PM
|
#10
|
LQ Newbie
Registered: Aug 2006
Location: Ukraine
Distribution: Debian Etch
Posts: 15
Original Poster
Rep:
|
Ok, i'll go little deeper.
Let's take the main_socket first.
Here is how it was declared:
Later it has been manipulated by this function:
Code:
int create_socket(uint16_t port){
/* Create a new socket unit */
int sock = socket(AF_INET, SOCK_DGRAM, 0);
struct sockaddr_in main_socket_name;
main_socket_name.sin_family = AF_INET;
main_socket_name.sin_port = htons(port);
main_socket_name.sin_addr.s_addr = htonl(INADDR_ANY);
/* Bind it to port */
if(bind(sock, (struct sockaddr *) &main_socket_name, sizeof(main_socket_name)) < 0){
perror("bind");
exit(EXIT_FAILURE);
}
return sock;
}
And assigned:
Code:
...
main_socket = create_socket(port); // port - global variable, == 4242 if user did not change it.
...
Now let's see what we have about sendstring.
It is assigned when i call the function mysend():
Code:
...
mysend("hello",¤d);
...
Tried to change sendstring to &sendstring but it did not help
The int sendstringlen is strlen(sendstring).
And the most interesting and important part - struct sockaddr_in current.
Declaration:
Code:
struct sockaddr_in current;
It was initially filled in this way:
Code:
void myrecv(const struct sockaddr_in *addr){
int addrlen = sizeof(struct sockaddr_in);
buflen = recvfrom(main_socket, buffer, BUFSIZE, 0, (struct sockaddr *)addr, &addrlen);
if(buflen == -1){
perror("recvfrom");
}
}
Code:
...
myrecv(¤t);
...
When someone connects, it sends the following: NEW myname, where myname is his id.
I successully receive this message, and call the client_new(char * login) function, which allocates memory for this guy and saves his id in that memory. When it is done, i should send him "hello" message:
Code:
mysend("hello",¤t);
What happens later we already know
That stupid bug seems to be somewhere deeper. But where?????
I test this server with simple client written in python, here is the code:
Code:
#!/usr/bin/python
import socket
import sys
# Collect info
username = raw_input("Your login plz: ")
servername = raw_input("Server hostname: ")
serverport = raw_input("And port plz (default: 4242) : ")
if serverport == "":
serverport = 4242
else: serverport = int(serverport)
serveraddr = ((servername, serverport))
# Have info, connect to the server
print "Connecting..."
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
# Send login info
sock.sendto("NEW %s" % username, serveraddr)
helloconfirm = sock.recv(256) # Here the server should send me "hello" message.
# Bug in the server! All i can do now is to kill this program.
# Send all what user types in, print all that server sends in
io = select((sys.stdin, sock), Null, Null, Null)
while(1):
if io[0] == sys.stdin:
# User typed something in termintal. Send it to the server
str = raw_input()
if str == "quit":
sock.close()
exit(0)
sock.sendto(str, serveraddr)
else:
# Server sent something in. Print it
str = sock.recv(256)
print str
It seems to be all.
|
|
|
11-03-2006, 01:00 PM
|
#11
|
LQ Newbie
Registered: Aug 2006
Location: Ukraine
Distribution: Debian Etch
Posts: 15
Original Poster
Rep:
|
Added the following to the mysend function:
Code:
if(debug){ // debug == 1
printf("main_socket == %d\n", main_socket);
printf("addr->sin_addr.s_addr == %d\n", addr->sin_addr.s_addr);
/* Tried also to use the inet_ntoa() function here but it causes a segfault. */
}
Here is what it prints when run:
Code:
main_socket == 4
addr->sin_addr.s_addr == 0 //??????
sendto: Invalid argument
Also tested this trough eth0 interface (i used loopback before) and this does not changed anything.
|
|
|
11-03-2006, 02:44 PM
|
#12
|
Member
Registered: May 2002
Location: new hampshire
Distribution: Fedora, RHEL
Posts: 600
Rep:
|
The answer is simple enough, I think.
Basically, you're assuming that the sockaddr_in is being correct assigned, but there is where you're incorrect.
On the stack, in myrecv(const struct sockaddr_in *addr), you are only modifying the local copy of addr. Try this, make it a **, use a local temporary copy (struct sockaddr *pSA = (sockaddr*)(*addr) that you pass to the function, and then memcpy it back (if(*addr != pSA)memcpy(*addr, pSA, sizeof(struct sockaddr)) and see if that works. My guess is that it will.
If that doesn't work, please post a full transcript of the program so that I can see exactly what happens.
-Aaron
|
|
|
11-04-2006, 07:06 AM
|
#13
|
LQ Newbie
Registered: Aug 2006
Location: Ukraine
Distribution: Debian Etch
Posts: 15
Original Poster
Rep:
|
It works!
I did not add the struct *pSA because the ** is too complicated for me(newbie in programming ), thanx anyway for pointing where the problem is.
Here's what i did:
1. changed struct sockaddr_in current to struct sockaddr_in *current.
2. used malloc(sizeof(struct sockaddr_in)) to allocate memory for it.
3. current is now address of struct sockaddr_in in memory, so i don't need to do ¤t anymore:
Code:
mysend("hello",current);
And i was surprised when it started to work
Thank You guys for support, see ya.
Last edited by Yury; 11-04-2006 at 07:13 AM.
|
|
|
All times are GMT -5. The time now is 12:22 AM.
|
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.
|
Latest Threads
LQ News
|
|