LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   accept() command of networking 3rd arg problem (https://www.linuxquestions.org/questions/programming-9/accept-command-of-networking-3rd-arg-problem-602819/)

likewater 11-27-2007 03:59 PM

accept() command of networking 3rd arg problem
 
Hello All,
I have started to study linux api networking,using a code for a server
I tryed to run it on linux ubuntu, kde/c++:


struct sockaddr_in serv_addr, cli_addr;
sockfd = socket(AF_INET,SOCK_STREAM,0);
clilen = sizeof(cli_addr);
newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);


has a problem at 3rd argumnet custing:

tryed to follow the Beej's Guide to Network Programming
and wrote:


clilen = sizeof(struct sockaddr_in);

newsockfd = accept(sockfd, (struct sockaddr *) &cli_addr, &clilen);


man pages also doesn't help
so how can i solve the problem?:confused:

LinuxManMikeC 11-27-2007 04:24 PM

What is the datatype of clilen?
What are your compiler errors/warnings?

The datatype of clilen should be socklen_t.
Remember to cast the sizeof return value to socklen_t.

likewater 11-28-2007 07:09 AM

now it works but still have network problem
 
Try to run client server application
running the client gave the message:

ERROR connecting: Network is unreachable

running the server gave the message:
ERROR on binding

tried to change port number but it doesn't help
may be the problem is that i try to run it at local loop back 127.0.0.0?

1. how can i solve the problem?
2. how can i detect free tcp port numbers at linux?

code server:
================================


#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>
//----------------------
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
using namespace std;



// return EXIT_SUCCESS;

//================================================================
// server
//===============================================================
void error ( char *msg )
{
char pause[2];
//perror(msg);
cout<<msg;
gets ( pause );
exit ( 1 );
}

/*int main(int argc, char *argv[])*/
int main()
{
int sockfd, newsockfd, portno;
socklen_t clilen;
char buffer[256];
char pause[2];
struct sockaddr_in serv_addr, cli_addr;
int n;
portno =10000;

/* if (argc < 2) {
fprintf(stderr,"ERROR, no port provided\n");
exit(1);
}*/
//-------------------------------------------------
sockfd = socket ( AF_INET,SOCK_STREAM,0 );
if ( sockfd < 0 )
error ( "ERROR opening socket" );
bzero ( ( char * ) &serv_addr, sizeof ( serv_addr ) );

/*portno = atoi(argv[1]);*/

serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = INADDR_ANY;
serv_addr.sin_port = htons ( portno );
if ( bind ( sockfd, ( struct sockaddr * ) &serv_addr,
sizeof ( serv_addr ) ) < 0 )
error ( "ERROR on binding" );
listen ( sockfd,5 );
clilen = sizeof ( cli_addr );

newsockfd = accept ( sockfd, ( struct sockaddr* ) &cli_addr,&clilen );
if ( newsockfd < 0 )
error ( "ERROR on accept" );
bzero ( buffer,256 );
n = read ( newsockfd,buffer,255 );
if ( n < 0 )
error ( "ERROR reading from socket" );
printf ( "Here is the message: %s\n",buffer );
n = write ( newsockfd,"I got your message",18 );
if ( n < 0 )
error ( "ERROR writing to socket" );

gets ( pause );
return EXIT_SUCCESS;
}
=========================================================
code client
=========================================================



#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <iostream>
#include <cstdlib>

using namespace std;

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

//========================================================================
// client //
//========================================================================

void error(char *msg) {
char pause[2];
perror(msg);
gets ( pause );
exit(0);
}

/*int main(int argc, char *argv[]) {*/
int main(){
int sockfd, portno, n;
struct sockaddr_in serv_addr; // -> sockaddr serv_addr;
struct hostent *server;
char buffer[256];

//if (argc < 3) {
// fprintf(stderr,"usage %s hostname port\n", argv[0]);
// exit(0);
//}
//portno = atoi(argv[2]);
portno =10000;
sockfd = socket(AF_INET, SOCK_STREAM, 0);
if (sockfd < 0)
error("ERROR opening socket");
// server = gethostbyname(argv[1]); //
server = gethostbyname("127.0.0.0");
if (server == NULL) {
fprintf(stderr,"ERROR, no such host\n");
exit(0);
}
bzero((char *) &serv_addr, sizeof(serv_addr));
serv_addr.sin_family = AF_INET;

bcopy((char *)server->h_addr, (char *) &serv_addr.sin_addr.s_addr, server->h_length);
serv_addr.sin_port = htons(portno);


if (connect(sockfd,(struct sockaddr *)&serv_addr,sizeof(serv_addr)) < 0)
error("ERROR connecting");
n = write(sockfd,"HELLO THERE",sizeof("HELLO THERE"));
if (n < 0)
error("ERROR writing to socket");
bzero(buffer,256);
n = read(sockfd,buffer,255);
if (n < 0)
error("ERROR reading from socket");
printf("%s\n",buffer);
return EXIT_SUCCESS;
}

LinuxManMikeC 11-28-2007 01:16 PM

If your "ERROR on binding" message is printing, then the problem isn't with accept(), it's with bind(). And I was asking about COMPILER errors/warnings, but providing the full source code served the same purpose.

It doesn't matter what address you are binding on, as long as its an address belonging to a network interface on your machine. Since you are using INADDR_ANY then its taken care of for you.

When socket functions such as bind() returns with an error (-1), they also set the global C variable errno. You can get further information from this variable with the following code:
Code:

#include <iostream>
#include <cerrno>  //Provides the errno variable
#include <cstring>  //Provides the strerror() function

using namespace std;

//Your code here...

if ( bind( /* Args... */ ) == -1 ) {
    cout << strerror(errno);
    //Your error handling here...
}

//More code...

I think you could have a potential problem with the datatype of portno. You have it as a plain old int (likely 32 bits, and signed) when it should be an unsigned short int (16 bits). When you run it through htons() (the 's' is for "short") it converts your int to an unsigned short int and reverses the byte order, potentially munging the port number in the process. For all you know it could be turning into port 0 or some such nonsense. Be careful with implicit casts.

Anyway, your code compiles and runs just fine here. Add some code to print out details on your bind() error and correct the datatype of portno, then we'll go from there.


All times are GMT -5. The time now is 09:00 PM.