Help...beginner at sockets

Help...beginner at sockets

Post by pdee » Fri, 23 Oct 1998 04:00:00



I've never coded any tcp stuff before and have problems with a test program
I'm writing which is supposed to create a socket connection to be connected
to by a local client process. The connect() gives me back a socket number of

listen() sometimes comes straight back and the accept() fails with EFAULT.
Sometimes the listen seems to work but when I try to connect with the client
process I get ECONNREFUSED.

Do I need to set up a an entry in the services file ?

I enclose the source below.

Thanks in advance for any replies

Regards
Peter Deed

/* --------------------- SERVER PROCESS ---------------*/
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>

struct servent *serviceent;
struct protoent *protocolent;
struct sockaddr *socketaddress;
struct sockaddr receiveaddress;

main()
{
 int  s;
 int  *addresslen;
 int  retval;
 struct sockaddr *receiveaddress;

 /* Get Service Entry */
 socketaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));
 receiveaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));
 protocolent=getprotobyname("tcp");

   s = socket(AF_INET, SOCK_STREAM, protocolent->p_proto);

 retval = bind ( s, socketaddress, 14 );
 retval = listen ( s, 6000 );
 retval = accept ( s, receiveaddress, addresslen );

Quote:}

/*------------------ CLIENT PROCESS ---------------------*/
#include <stdio.h>
#include <sys/socket.h>
#include <netdb.h>
#include <errno.h>

//struct servent *serviceent;
struct sockaddr *socketaddress;

main()
{
 int  s;
 int  retval;

 /* Get Service Entry */

 socketaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));

   s = socket(AF_INET, SOCK_STREAM, 6);

 socketaddress->sa_family = AF_INET;

 retval = connect ( s, socketaddress, 7 );

Quote:}

 
 
 

Help...beginner at sockets

Post by Paul F- » Sat, 24 Oct 1998 04:00:00



> I've never coded any tcp stuff before and have problems with a test program
> I'm writing which is supposed to create a socket connection to be connected
> to by a local client process. The connect() gives me back a socket number of

> listen() sometimes comes straight back and the accept() fails with EFAULT.
> Sometimes the listen seems to work but when I try to connect with the client
> process I get ECONNREFUSED.

> Do I need to set up a an entry in the services file ?

> I enclose the source below.

> Thanks in advance for any replies

> Regards
> Peter Deed

> /* --------------------- SERVER PROCESS ---------------*/
> #include <stdio.h>
> #include <sys/socket.h>
> #include <netdb.h>
> #include <errno.h>

> struct servent *serviceent;
> struct protoent *protocolent;
> struct sockaddr *socketaddress;
> struct sockaddr receiveaddress;

> main()
> {
>  int  s;
>  int  *addresslen;
>  int  retval;
>  struct sockaddr *receiveaddress;

>  /* Get Service Entry */

why malloc these - just define them as struct sockaddr receiveaddress
and pass &receiveaddress etc... to the bind/accept calls

Quote:>  socketaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));
>  receiveaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));

minor point - what if socket/receiveaddress is NULL

Quote:>  protocolent=getprotobyname("tcp");

you don't _need_ to set protocolent - you can use 0 - which will use the
right number for tcp (6 I beleive)

Quote:>    s = socket(AF_INET, SOCK_STREAM, protocolent->p_proto);

might be nice to see if s isn't -1

woa!!!!

1) - you need to blank out socketaddress or else god knows what you're
asking to bind to
2) - what is '14' how about sizeof(struct sockaddr) (which should be 16
anyway)
3) - check retval and (if non zero) - use perror("bind") - it's
wonderfully helpful
4) - what port are you binding to.  Either you need to specify a port
before you bind (in a sockaddr_in structure which you then memcpy into
the sockaddr structure (or just cast it on the bind/accept if lazy)) -
OR you read it out of a sockaddr_in structure _after_ the bind (to port
0) to see which port you've been given.

Quote:>  retval = bind ( s, socketaddress, 14 );

1) - 6000 is a _little_ excessive.  You'll probably find the system
maximum is 5 :-)))
2) - listen doesn't actually _do_ anything - it just tell the O/S how to
deal with your socket so it should just come right back.
3) - go on - check retval - it's good for your soul

Quote:>  retval = listen ( s, 6000 );

1) - be nice to accept - memset receiveaddress to NULLs
2) - set *addresslen to sizeof(struct sockaddr) before you call
3) - umm - accept returns your shiny new socket - you _probably_ don't
want to call it retval.
4) - again - pesky error checking - if the returned socket is -1 perror
is a _must_

- Show quoted text -

Quote:>  retval = accept ( s, receiveaddress, addresslen );

> }

> /*------------------ CLIENT PROCESS ---------------------*/
> #include <stdio.h>
> #include <sys/socket.h>
> #include <netdb.h>
> #include <errno.h>

> //struct servent *serviceent;
> struct sockaddr *socketaddress;

> main()
> {
>  int  s;
>  int  retval;

>  /* Get Service Entry */

>  socketaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));

6 - no - use 0 - let the O/S decide :-))

Quote:>    s = socket(AF_INET, SOCK_STREAM, 6);

go on - be a devil - check that s isn't -1

Quote:

>  socketaddress->sa_family = AF_INET;


supposed to do.  In a _normal_ situation - I'd expect you to set
sin_family, sin_port (which you need to know from the discussion about
'bind' above) and sin_addr.s_addr in a sockaddr_in structure (don't
forget to memset to NULL first :-)) and then copy that into a sockaddr
structure for the connect call.  If this is some use of AF_INET sockets


sensible port number if you are treating the sa_data back from the bind
as a string (which it isn't).

7 ?? what's 7 ?? sizeof(struct sockaddr) again perchance ??

Quote:>  retval = connect ( s, socketaddress, 7 );

> }

fundamentally

1) check for errors
2) use struct sockaddr_in to set/read values for the calls - memcpy
to/from struct sockaddr for the actual calls themselves
3) use sizeof() - it's your friend.
4) let protocol default from 0 in socket() calls
5) always memset() address buffer for socket calls to ensure no *is
* around
6) man listen, man SSC accept, man bind, man socket and man connect -
all dead useful

have fun,
Paul

 
 
 

Help...beginner at sockets

Post by Brian McCaule » Sat, 24 Oct 1998 04:00:00



> I've never coded any tcp stuff before and have problems with a test program
> I'm writing which is supposed to create a socket connection to be connected
> to by a local client process.

You should consider investing in a book on programming for Unix.

A book on C too may help too - you don't seem to understand how
pointers work.

You should definitely get the socket programming FAQ.

Quote:> The connect() gives me back a socket number of 3

Nonsense.  connect() does not return a socket number.  It returns 0 or
-1.

Nonsense.  bind() does not return a string.  It returns 0 or -1.

Quote:> The subsequent
> listen() sometimes comes straight back and the accept() fails with EFAULT.
> Sometimes the listen seems to work but when I try to connect with the client
> process I get ECONNREFUSED.
> Do I need to set up a an entry in the services file ?

If you want to use setservbyname().

Quote:> /* --------------------- SERVER PROCESS ---------------*/
> #include <stdio.h>
> #include <sys/socket.h>
> #include <netdb.h>
> #include <errno.h>

> struct servent *serviceent;
> struct protoent *protocolent;
> struct sockaddr *socketaddress;

Since these are IP sockets it would be simpler to use

struct sockaddr_in *socketaddress;

Quote:> struct sockaddr receiveaddress;

> main()
> {
>  int  s;
>  int  *addresslen;

No not int*.

int addresslen;

Quote:>  int  retval;
>  struct sockaddr *receiveaddress;

>  /* Get Service Entry */

Nice comment - where's the code to go with it?

Quote:>  socketaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));
>  receiveaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));

Why are you using heap for these structres?  Why not just ordinary
"auto" variables?

Quote:>  protocolent=getprotobyname("tcp");

>    s = socket(AF_INET, SOCK_STREAM, protocolent->p_proto);

Ditch the protocolent stuff.  AF_INET, SOCK_STREAM uniqiuely identify
TCP already.

   s = socket(AF_INET, SOCK_STREAM, 0);

Quote:>  retval = bind ( s, socketaddress, 14 );

socketaddress points to allocated but initialised memory.  You must
put stuff in there.  Do not hard code the size as 14.

socketaddress->sin_family=AF_INET;
socketaddress->sin_port = htons(sericeent->s_port);
socketaddress->sin_addr.s_addr = htonl(INADDR_ANY);

retval = bind ( s, socketaddress, sizeof(*socketaddress) );

Quote:>  retval = listen ( s, 6000 );
>  retval = accept ( s, receiveaddress, addresslen );

addresslen would be a an unitialised poiter actually you should
declare addresslen as int (see above) and do:

addrlen=sizeof(*receiveaddress);
retval = accept ( s, receiveaddress, &addresslen );

Quote:> /*------------------ CLIENT PROCESS ---------------------*/
> #include <stdio.h>
> #include <sys/socket.h>
> #include <netdb.h>
> #include <errno.h>

> //struct servent *serviceent;
> struct sockaddr *socketaddress;

struct sockaddr_in *socketaddress;

Quote:

> main()
> {
>  int  s;
>  int  retval;

>  /* Get Service Entry */

>  socketaddress=(struct sockaddr*)malloc(sizeof(struct sockaddr));

>    s = socket(AF_INET, SOCK_STREAM, 6);

Not 6.  0.  See above.

Quote:

>  socketaddress->sa_family = AF_INET;

socketaddress->sin_family = AF_INET;

Nonsense.  Gibberish.  Gobbldygook.  You need to specify and IP
address and port.

Quote:>  retval = connect ( s, socketaddress, 7 );

 retval = connect ( s, socketaddress, sizeof(*socketaddress) );

--

  .  _\\__[oo   faeces from    | Phones: +44 121 471 3789 (home)

 .  l___\\    /~~) /~~[  /   [ | PGP-fp: D7 03 2A 4B D8 3A 05 37...
  # ll  l\\  ~~~~ ~   ~ ~    ~ | http://www.wcl.bham.ac.uk/~bam/
 ###LL  LL\\ (Brian McCauley)  |

 
 
 

1. beginner needs help with sockets

I need to communicate with a UNIX machine to a Win95 PC over the internet for
both "client and server" application. For the PC I have some subroutines
such as "TCP read" which handle all of the programming. On the UNIX machine,
I don't have any special routines. I've been told that I need to use a socket
interface in a C program to do this.
Can anyone give me any clues as to how to go about doing this. I am using
a C program in UNIX. Source code would be extremly useful.
Thanks a million,

2. Linux Fax Server/Printer

3. Beginner needs help with sockets!

4. FreeBSD books

5. beginner socket question

6. 96MB memory gets my Computer STUCK -- What to DO???

7. sockets beginner

8. awe64 midi

9. beginner socket programming problem

10. sockets under ESIX Rev. D - beginner's question

11. socket beginner: developping inetd subserver

12. Beginners: Here's the beginners web info you've been looking for

13. Help Apache - getsockname: Socket operation on non-socket