Home > Archive > Unix Programming > November 2004 > socket programming UDP help
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
socket programming UDP help
|
|
|
| Hi all,
I am trying to learn C socket programming and I have a small program
which is a UP client.
The problem is, when I run the program, I get a runtime error -
"Invalid Argument" - from a call to sendto.
I was hoping that if someone has the time they could take a look at my
code posted below and let me know what i'm doing wrong?
Thanks in advance,
Ted
/******************************* start
***********************************/
#include <stdio.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
extern int errno;
#define LINELEN 128
#define BUFFLEN 120
struct sockaddr_in * getserveraddr ( char *, char * ) ;/* return
server add */
int main( argc, argv )
int argc;
char *argv[];
{
char *host; /*used to hold name of host */
char *service; /* used to hold port no. as a string */
if( argc == 3 ) {
host = argv[ 1 ];
service = argv[ 2 ];
}
else {
fprintf( stderr, "usage: UDPConn [ host [ port ] ]\n" );
exit( 1 );
}
UDPConn( host, service );
exit( 0 );
}
/*------------------------------------------------------------------------
* UDPConn - send input to ECHO service on specified host and print
reply
*------------------------------------------------------------------------
*/
int UDPConn( host, service )
char *host;
char *service;
{
char buff[ 120 ]="whattime";
int s; /* counter */
int sockno ; /*server socket number */
struct sockaddr_in *addrptr;
//int i;
//int now;
sockno = socket( PF_INET, SOCK_DGRAM, 0 );
if( sockno < 0 ) {
perror( "Cannot open socket...\n" );
}
(struct sockaddr *)addrptr = getserveraddr( host, service );
sendto( sockno, (char *)&buff, sizeof( buff ), 0,
(struct sockaddr *)&addrptr, sizeof( struct sockaddr) );
fprintf(stderr,"after call to sendto in
Client >> %s\n",strerror( errno ) ); //error
"invalid argu..."
....
....
return 0;
}
/*------------------------------------------------------------------------
* getsererveraddr - get server address and put it in servadd
*------------------------------------------------------------------------
*/
struct sockaddr_in * getserveraddr( char *host, char *service) /*
port number as a character string */
{
static struct sockaddr_in servadd; /* structure to hold server
address */
struct hostent *phe;
int s, type;
bzero((char *)&servadd, sizeof( servadd ) );
servadd.sin_family = AF_INET; /* TCP/IP address family*/
if ( ( servadd.sin_port = htons( (ushort)atoi( service ) ) ) == 0 )
{
fprintf( stderr, "cant get \"%s\" service entry\n", service );
//exit(NULL ); // warnings here?
}
if(phe = gethostbyname(host))
bcopy (phe->h_addr,(char*)&servadd.sin_addr,phe->h_length);
else
{fprintf(stderr, "can't get \"%s\"host entry\n",host);
// exit (NULL ); // warnings here?
} return ( &servadd);
}
| |
| Barry Margolin 2004-11-18, 8:58 am |
| In article <d9aad52e.0411180122.12fad13@posting.google.com>,
johnston_58@hotmail.com (Ted) wrote:
> /*------------------------------------------------------------------------
> * getsererveraddr - get server address and put it in servadd
> *------------------------------------------------------------------------
> */
> struct sockaddr_in * getserveraddr( char *host, char *service) /*
> port number as a character string */
> {
> static struct sockaddr_in servadd; /* structure to hold server
> address */
> struct hostent *phe;
> int s, type;
>
> bzero((char *)&servadd, sizeof( servadd ) );
> servadd.sin_family = AF_INET; /* TCP/IP address family*/
>
> if ( ( servadd.sin_port = htons( (ushort)atoi( service ) ) ) == 0 )
> {
> fprintf( stderr, "cant get \"%s\" service entry\n", service );
> //exit(NULL ); // warnings here?
> }
>
> if(phe = gethostbyname(host))
> bcopy (phe->h_addr,(char*)&servadd.sin_addr,phe->h_length);
> else
> {fprintf(stderr, "can't get \"%s\"host entry\n",host);
> // exit (NULL ); // warnings here?
> } return ( &servadd);
> }
You're returning a pointer to an automatic variable. This pointer
becomes invalid when the function returns. The space used by the
servadd structure is likely being overwritten before you call servadd.
You need to use malloc() to allocate the structure dynamically -- and
then call free() in the caller.
--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***
| |
| Wayne C. Morris 2004-11-18, 3:59 pm |
| In article <barmar-E8E45B.05071618112004@comcast.dca.giganews.com>,
Barry Margolin <barmar@alum.mit.edu> wrote:
> In article <d9aad52e.0411180122.12fad13@posting.google.com>,
> johnston_58@hotmail.com (Ted) wrote:
>
[snip][color=darkred]
>
> You're returning a pointer to an automatic variable. This pointer
> becomes invalid when the function returns. The space used by the
> servadd structure is likely being overwritten before you call servadd.
No, he's not returning a pointer to an automatic variable.
Did you miss the 'static' keyword?
| |
| Fletcher Glenn 2004-11-18, 3:59 pm |
|
"Ted" <johnston_58@hotmail.com> wrote in message
news:d9aad52e.0411180122.12fad13@posting.google.com...
> Hi all,
>
> I am trying to learn C socket programming and I have a small program
> which is a UP client.
> The problem is, when I run the program, I get a runtime error -
> "Invalid Argument" - from a call to sendto.
>
> I was hoping that if someone has the time they could take a look at my
> code posted below and let me know what i'm doing wrong?
>
> Thanks in advance,
>
> Ted
>
> /******************************* start
> ***********************************/
> #include <stdio.h>
> #include <errno.h>
> #include <sys/types.h>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <netdb.h>
> extern int errno;
>
> #define LINELEN 128
> #define BUFFLEN 120
>
> struct sockaddr_in * getserveraddr ( char *, char * ) ;/* return
> server add */
>
> int main( argc, argv )
> int argc;
> char *argv[];
> {
> char *host; /*used to hold name of host */
> char *service; /* used to hold port no. as a string */
>
> if( argc == 3 ) {
> host = argv[ 1 ];
> service = argv[ 2 ];
> }
> else {
> fprintf( stderr, "usage: UDPConn [ host [ port ] ]\n" );
> exit( 1 );
> }
> UDPConn( host, service );
> exit( 0 );
> }
>
> /*------------------------------------------------------------------------
> * UDPConn - send input to ECHO service on specified host and print
> reply
> *------------------------------------------------------------------------
> */
> int UDPConn( host, service )
> char *host;
> char *service;
> {
> char buff[ 120 ]="whattime";
> int s; /* counter */
> int sockno ; /*server socket number */
> struct sockaddr_in *addrptr;
> //int i;
> //int now;
>
> sockno = socket( PF_INET, SOCK_DGRAM, 0 );
> if( sockno < 0 ) {
> perror( "Cannot open socket...\n" );
> }
> (struct sockaddr *)addrptr = getserveraddr( host, service );
> sendto( sockno, (char *)&buff, sizeof( buff ), 0,
> (struct sockaddr *)&addrptr, sizeof( struct sockaddr) );
> fprintf(stderr,"after call to sendto in
> Client >> %s\n",strerror( errno ) ); //error
It's not valid to examine errno if you have not tested the return value
from sendto. It's possible that sendto succeeded, and therefore errno
can be a random value that is meaningless.
--
Fletcher Glenn
> "invalid argu..."
> ...
> ...
>
> return 0;
> }
>
> /*------------------------------------------------------------------------
> * getsererveraddr - get server address and put it in servadd
> *------------------------------------------------------------------------
> */
> struct sockaddr_in * getserveraddr( char *host, char *service) /*
> port number as a character string */
> {
> static struct sockaddr_in servadd; /* structure to hold server
> address */
> struct hostent *phe;
> int s, type;
>
> bzero((char *)&servadd, sizeof( servadd ) );
> servadd.sin_family = AF_INET; /* TCP/IP address family*/
>
> if ( ( servadd.sin_port = htons( (ushort)atoi( service ) ) ) == 0 )
> {
> fprintf( stderr, "cant get \"%s\" service entry\n", service );
> //exit(NULL ); // warnings here?
> }
>
> if(phe = gethostbyname(host))
> bcopy (phe->h_addr,(char*)&servadd.sin_addr,phe->h_length);
> else
> {fprintf(stderr, "can't get \"%s\"host entry\n",host);
> // exit (NULL ); // warnings here?
> } return ( &servadd);
> }
| |
| Fletcher Glenn 2004-11-18, 3:59 pm |
|
"Barry Margolin" <barmar@alum.mit.edu> wrote in message
news:barmar-E8E45B.05071618112004@comcast.dca.giganews.com...
> In article <d9aad52e.0411180122.12fad13@posting.google.com>,
> johnston_58@hotmail.com (Ted) wrote:
>
>
> You're returning a pointer to an automatic variable. This pointer
> becomes invalid when the function returns. The space used by the
> servadd structure is likely being overwritten before you call servadd.
>
> You need to use malloc() to allocate the structure dynamically -- and
> then call free() in the caller.
>
> --
> Barry Margolin, barmar@alum.mit.edu
> Arlington, MA
> *** PLEASE post questions in newsgroups, not directly to me ***
Barry,
That's not true. He has declared his return value to be "static", which
means
that it is valid. The real problem is that he is not testing the return
value from
sendto.
--
Fletcher Glenn
| |
| Wayne C. Morris 2004-11-18, 3:59 pm |
| In article <d9aad52e.0411180122.12fad13@posting.google.com>,
johnston_58@hotmail.com (Ted) wrote:
> int UDPConn( host, service )
> char *host;
> char *service;
> {
> char buff[ 120 ]="whattime";
> int s; /* counter */
> int sockno ; /*server socket number */
> struct sockaddr_in *addrptr;
> //int i;
> //int now;
>
> sockno = socket( PF_INET, SOCK_DGRAM, 0 );
> if( sockno < 0 ) {
> perror( "Cannot open socket...\n" );
> }
> (struct sockaddr *)addrptr = getserveraddr( host, service );
> sendto( sockno, (char *)&buff, sizeof( buff ), 0,
> (struct sockaddr *)&addrptr, sizeof( struct sockaddr) );
You should be passing addrptr, not &addrptr. addrptr is a pointer to the
structure, whereas &addrptr is a pointer to a pointer to the structure.
|
|
|
|
|