Networking Forums

Networking Forums > Computer Networking > Linux Networking > Error in accept() system call

Reply
Thread Tools Display Modes

Error in accept() system call

 
 
Santosh Golecha
Guest
Posts: n/a

 
      08-13-2003, 02:54 AM
Hello,

I am using Linux 2.4.18 kernel to do some simple network programming.
I wrote a simple TCP client/server example which is shown below. My
problem is that when the client tries to connect to the server, I get
an error:

Error 22
Invalid Argument

I get this error when the server accepts connection from the client
i.e in the accept() system call.

When I try the same example but with a UDP server( Datagram socket and
no accept system call) and a client it works. I dont know why I keep
getting this error. I would appreciate any help on this.

Code Listing
------------

server.c

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char *argv[]){

int sockfd, nsockfd;
struct sockaddr_in servaddr, cliaddr;
int m,n;
socklen_t len, clilen;
char msg[1000];

sockfd = socket(AF_INET, SOCK_STREAM, 0);

bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(32000);

/* Bind the socket and check for errors */
if(bind(sockfd , (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0
)
{
printf("Error binding Server Socket: ErrorNo:%d\n",errno);
perror("Meaning :");
exit(1);
}

/* Listen at the particular socket */
if(listen(sockfd ,5) < 0 )
{
printf("Error listening Server Socket. ErrorNo: %d\n",errno);
perror("Meaning :");
exit(1);
}

for( ; {
// Error occurs here
if(( nsockfd = accept(sockfd ,(struct sockaddr *) &cliaddr ,
&clilen) ) < 0 )
{
printf("Error accepting connection. ErrorNo: %d\n",errno);
perror("Meaning :");
close(sockfd);
exit(1);
}
else
{
m = read(sockfd, msg, 1000);
n = write(sockfd, msg, 1000);
printf("-------------------------------------\n");
msg[m] = '\0';
printf("Received the following message\n");
printf("%s", msg);
close(nsockfd);
}
}

close(sockfd);
return 0;
}


client.c
--------

#include <sys/socket.h>
#include <netinet/in.h>
#include <stdio.h>
#include <errno.h>

int main(int argc, char *argv[]){

int sockfd;
struct sockaddr_in servaddr, cliaddr;
int m,n;
char sendline[1000];
char recvline[1000];


bzero(&servaddr, sizeof(servaddr));
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = inet_addr(argv[1]);
servaddr.sin_port = htons(32000);

sockfd = socket(AF_INET, SOCK_STREAM, 0);

if(connect(sockfd,(struct sockaddr *) &servaddr ,sizeof(struct
sockaddr)) < 0)
{
printf("Error Connecting to server. ErrorNo: %d",errno);
perror("Meaning :");
close(sockfd);
exit(1);
}


while(fgets(sendline, 1000, stdin) != NULL){

m = write(sockfd, sendline, 1000);
n = recvfrom(sockfd, recvline,1000, 0 , NULL, NULL);
recvline[n] = '\0';

printf("-----------------------------------------\n");
printf("Message received from server\n");
fputs(recvline, stdout);
}

close(sockfd);
return 0;
}
 
Reply With Quote
 
 
 
 
Chris Fowler
Guest
Posts: n/a

 
      08-13-2003, 03:17 AM
In the server code you need to read and write to nsockfd. This
is the fd that was given to you by accept(). Make sure you also
close nsokffd when complete.


Santosh Golecha wrote:

> Hello,
>
> I am using Linux 2.4.18 kernel to do some simple network programming.
> I wrote a simple TCP client/server example which is shown below. My
> problem is that when the client tries to connect to the server, I get
> an error:
>
> Error 22
> Invalid Argument
>
> I get this error when the server accepts connection from the client
> i.e in the accept() system call.
>
> When I try the same example but with a UDP server( Datagram socket and
> no accept system call) and a client it works. I dont know why I keep
> getting this error. I would appreciate any help on this.
>
> Code Listing
> ------------
>
> server.c
>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <stdio.h>
> #include <errno.h>
>
> int main(int argc, char *argv[]){
>
> int sockfd, nsockfd;
> struct sockaddr_in servaddr, cliaddr;
> int m,n;
> socklen_t len, clilen;
> char msg[1000];
>
> sockfd = socket(AF_INET, SOCK_STREAM, 0);
>
> bzero(&servaddr, sizeof(servaddr));
> servaddr.sin_family = AF_INET;
> servaddr.sin_addr.s_addr = inet_addr(argv[1]);
> servaddr.sin_port = htons(32000);
>
> /* Bind the socket and check for errors */
> if(bind(sockfd , (struct sockaddr *) &servaddr, sizeof(servaddr)) < 0
> )
> {
> printf("Error binding Server Socket: ErrorNo:%d\n",errno);
> perror("Meaning :");
> exit(1);
> }
>
> /* Listen at the particular socket */
> if(listen(sockfd ,5) < 0 )
> {
> printf("Error listening Server Socket. ErrorNo: %d\n",errno);
> perror("Meaning :");
> exit(1);
> }
>
> for( ; {
> // Error occurs here
> if(( nsockfd = accept(sockfd ,(struct sockaddr *) &cliaddr ,
> &clilen) ) < 0 )
> {
> printf("Error accepting connection. ErrorNo: %d\n",errno);
> perror("Meaning :");
> close(sockfd);
> exit(1);
> }
> else
> {
> m = read(sockfd, msg, 1000);
> n = write(sockfd, msg, 1000);
> printf("-------------------------------------\n");
> msg[m] = '\0';
> printf("Received the following message\n");
> printf("%s", msg);
> close(nsockfd);
> }
> }
>
> close(sockfd);
> return 0;
> }
>
>
> client.c
> --------
>
> #include <sys/socket.h>
> #include <netinet/in.h>
> #include <stdio.h>
> #include <errno.h>
>
> int main(int argc, char *argv[]){
>
> int sockfd;
> struct sockaddr_in servaddr, cliaddr;
> int m,n;
> char sendline[1000];
> char recvline[1000];
>
>
> bzero(&servaddr, sizeof(servaddr));
> servaddr.sin_family = AF_INET;
> servaddr.sin_addr.s_addr = inet_addr(argv[1]);
> servaddr.sin_port = htons(32000);
>
> sockfd = socket(AF_INET, SOCK_STREAM, 0);
>
> if(connect(sockfd,(struct sockaddr *) &servaddr ,sizeof(struct
> sockaddr)) < 0)
> {
> printf("Error Connecting to server. ErrorNo: %d",errno);
> perror("Meaning :");
> close(sockfd);
> exit(1);
> }
>
>
> while(fgets(sendline, 1000, stdin) != NULL){
>
> m = write(sockfd, sendline, 1000);
> n = recvfrom(sockfd, recvline,1000, 0 , NULL, NULL);
> recvline[n] = '\0';
>
> printf("-----------------------------------------\n");
> printf("Message received from server\n");
> fputs(recvline, stdout);
> }
>
> close(sockfd);
> return 0;
> }


 
Reply With Quote
 
beltorak
Guest
Posts: n/a

 
      08-13-2003, 07:02 AM
(E-Mail Removed) (Santosh Golecha) wrote in message news:<(E-Mail Removed). com>...
> Hello,
>


> // Error occurs here
> if(( nsockfd = accept(sockfd ,(struct sockaddr *) &cliaddr ,
> &clilen) ) < 0 )
> {
> printf("Error accepting connection. ErrorNo: %d\n",errno);
> perror("Meaning :");
> close(sockfd);
> exit(1);
> }
> else
> {


Actually, you are wrong. Your error occurs here.
> m = read(sockfd, msg, 1000);
> n = write(sockfd, msg, 1000);
> printf("-------------------------------------\n");
> msg[m] = '\0';
> printf("Received the following message\n");
> printf("%s", msg);
> close(nsockfd);
> }
> }
>
> close(sockfd);
> return 0;
> }
>


According to the man page for accept, it returns a new fd for the
connected socket (which you assigned to 'nsockfd'), but leaves the
original in the listen state; so you are trying to read from & write
to a 'listening' and not 'connected' socket. Change your reads and
writes.

Also, your procedure for printing errors lacks; perror() uses the
extern int errno for it's error messages; some library functions
(printf()) overwrite that number even if the overall function was a
success.... you are getting the wrong error messages. do:
----
extern int errno;
int errnum;
main() { etc etc
----

and then replace each of your error reporting functions with something
like:
----
if( this() < 0 ) {
errnum = errno;
perror("Error doing this");
fprintf(stdout, "Error Number %d\n", errnum);
exit(EXIT_FAIL);
}
----
Make a wrapper (perr( char* ) { ... }) for it; save some typing.

That should help you track down the errors a little better. I keep
getting a broken pipe. Don't forget to surround your read()s and
write()s (and maybe close()s, sometimes a write error won't be caught
until the fd is closed IIRC).

Also, look into strerror_r() which will fill a string buffer with the
error message, since perror() and strerror() are not threadsafe (if
two threads try to report different errors, one will clobber the
other).

Hope that helps.

-t.
 
Reply With Quote
 
Villy Kruse
Guest
Posts: n/a

 
      08-13-2003, 07:32 AM
On 13 Aug 2003 00:02:47 -0700,
beltorak <(E-Mail Removed)> wrote:


>extern int errno;


Carefull, these days errno is often a macro which calls a function returning
a pointer to an int and the macro then dereference this macro so it appears to
work like a variable called errno.

>int errnum;
>main() { etc etc




Example from GNU glibc2:

/usr/include/bits/errno.h:#define errno (*__errno_location ())

This is necessary for supporting threaded code.

The proper way to define errno is to #include <errno.h>



Villy
 
Reply With Quote
 
nzwwbtyb@soszoe.com.jk
Guest
Posts: n/a

 
      08-14-2003, 03:48 AM
Try this:

| }
|
| for( ; {
clilen = sizeof(cliaddr);
| if(( nsockfd = accept(sockfd ,(struct sockaddr *) &cliaddr
|, &clilen) ) < 0 )
| {

See this paragraph in man 2 accept for the reason.

The argument addr is a pointer to a sockaddr structure. This structure
is filled in with the address of the connecting entity, as known to the
communications layer. The exact format of the address passed in the
addr parameter is determined by the socket's family (see socket(2) and
the respective protocol man pages). The addrlen argument is a value-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
result parameter: it should initially contain the size of the structure
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
pointed to by addr; on return it will contain the actual length (in
^^^^^^^^^^^^^^^^^^^^^
bytes) of the address returned. When addr is NULL nothing is filled in.

By the way if you compile with -Wall you will notice lots of warnings
which you should fix if you really want your code to be portable. Also
note that inet_addr is deprecated and it returns the wrong type for
assignment to sin_addr anyway.
--

 
Reply With Quote
 
Santosh Golecha
Guest
Posts: n/a

 
      08-14-2003, 03:52 PM
Thanks...it worked. The only change I made as per your recommendation
was to add the following statement before the accept system call.

clilen = sizeof(cliaddr);

Thanks


(E-Mail Removed) wrote in message news:<tED_a.33167$(E-Mail Removed)>...
> Try this:
>
> | }
> |
> | for( ; {
> clilen = sizeof(cliaddr);
> | if(( nsockfd = accept(sockfd ,(struct sockaddr *) &cliaddr
> |, &clilen) ) < 0 )
> | {
>
> See this paragraph in man 2 accept for the reason.
>
> The argument addr is a pointer to a sockaddr structure. This structure
> is filled in with the address of the connecting entity, as known to the
> communications layer. The exact format of the address passed in the
> addr parameter is determined by the socket's family (see socket(2) and
> the respective protocol man pages). The addrlen argument is a value-
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> result parameter: it should initially contain the size of the structure
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^
> pointed to by addr; on return it will contain the actual length (in
> ^^^^^^^^^^^^^^^^^^^^^
> bytes) of the address returned. When addr is NULL nothing is filled in.
>
> By the way if you compile with -Wall you will notice lots of warnings
> which you should fix if you really want your code to be portable. Also
> note that inet_addr is deprecated and it returns the wrong type for
> assignment to sin_addr anyway.
> --

 
Reply With Quote
 
 
 
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
net use; system error 53 Dipesh_Sharma Windows Networking 6 05-30-2010 04:38 PM
Error "System error 5 has occurred" trying to set the system time using NET TIME on XP Spin Windows Networking 3 05-30-2009 02:52 AM
VoIP CALL BACK system - world best & newest 1GLOBALFone Broadband 1 02-11-2005 11:52 PM
System error 5 =?Utf-8?B?aGFyb2xk?= Windows Networking 1 12-16-2004 02:51 AM
Call abroad for the price of a national call bbp Broadband 2 10-23-2003 11:02 PM



1 2 3 4 5 6 7 8 9 10 11