ProgrammingThis 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.
So I'm working on creating a GUI interface for a program someone else wrote at my lab (who does not work here anymore). The main program itself sends commands to a robotic arm that brings metal samples into and out of a furnace.
This program *used* to work just fine, but that is not the case anymore.. The program has 3 parts to it, the GUI, the daemon process, and the client process. The daemon process sends the controls to the robot, and the client process sends commands to the daemon via tcp.
The problem comes up when this code is executed:
Code:
/* connect to the remote host/service */
if( connect( c->socket , (struct sockaddr*)&c->sin , sizeof(c->sin)) < 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot connect to \"%s.%s\" in net_conn_open: %s\n" , host , service , strerror( errno ) ) ;
#endif
net_conn_close( c ) ;
return( -1 ) ;
}
connect() returns the error code ECONNREFUSED (Connection Refused).
I don't believe anything is wrong with the code because it used to work just fine, but I don't know how to get it working again.
The service that this program uses to send the commands through the tcp is called xy_table, so I added the following line to /etc/services
xy_table 60200/tcp
I am running ubuntu 11.10
Does anyone have any suggestions of how I can get this working again?
EDIT: I forgot to mention that the host this program uses is localhost
Last edited by mfziegler; 02-09-2012 at 01:08 PM.
Reason: Added more information
The command "netstat -antp" should show you what ports and processes are doing listening. Run via sud to see the processes of other users. Check if something is listening to port 60200. If not, you need to find the program that is supposed to listen, and get it running.
netstat -antp doesn't list the program that is supposed to be listening; however, when I use ps aux, it shows the process that is supposed to be listening is running. Do you have any suggestions on how to set up the process to listen over this port?
netstat -antp doesn't list the program that is supposed to be listening; however, when I use ps aux, it shows the process that is supposed to be listening is running. Do you have any suggestions on how to set up the process to listen over this port?
You can also use telnet to verify if an app is listening on the particular port.
As for your app, that is supposed to open a socket and bind to that port, you need to show the code you have written thus far, since of course, how to actually perform the steps to setup this socket varies from one programming language to another.
netstat -antp doesn't list the program that is supposed to be listening; however, when I use ps aux, it shows the process that is supposed to be listening is running. Do you have any suggestions on how to set up the process to listen over this port?
What program is supposed to be listening? If it is one written by that programmer that is not longer around, you'll need to look for documentation and source code, if any.
You can also use telnet to verify if an app is listening on the particular port.
As for your app, that is supposed to open a socket and bind to that port, you need to show the code you have written thus far, since of course, how to actually perform the steps to setup this socket varies from one programming language to another.
I'll post the code tomorrow when I get back on my work computers, but it's saturated between 5 classes or so. There's a class main.xy_tablec.cc that calls xy_tablec.c that calls, xy_table.c, that calls robot_conn.c that calls net_conn.c. From my understanding, there are various structs that get built up along the way, and net_conn.c establishes the connection based on the values in these structs. The problem is that the code is not documented at all, and there are no in line comments either, so it is pretty hard for me to follow.
Quote:
What program is supposed to be listening? If it is one written by that programmer that is not longer around, you'll need to look for documentation and source code, if any.
There is a program called xy_tabled which is the daemon designed by that programmer to control the xy_table step motor. Originally, this program was designed on a Gentoo installation, but that computer died.. I installed gentoo on another computer, and it worked just fine... for a while. Then it hadn't been used in 2 months, and I got an error along the lines of "cannot map service (xy_table) over connection (tcp)". That, along with a lot of other issues with the gentoo installation, caused me to put Ubuntu 11.10 on the machine. Originally when I ran the program, I got the same error, but then when I added the service xy_table to the /etc/services file, the program got a little farther, and then gave me the error message described in my first post.
The original code has not changed at all, and I even reverted back to an old version of this software, and that still does not work. Considering the same code used to work, I'm thinking it may not be a programming error? But I'm really just lost at this point
I'll post the code tomorrow when I get back on my work computers, but it's saturated between 5 classes or so. There's a class main.xy_tablec.cc that calls xy_tablec.c that calls, xy_table.c, that calls robot_conn.c...
Looks like the app is a cross between C++ and C.
Quote:
Originally Posted by mfziegler
The problem is that the code is not documented at all, and there are no in line comments either, so it is pretty hard for me to follow.
Search the code for a bind() function call. That area of the code will put you in the ballpark as to where the socket, and the interface it is using, is bound to the port (60200).
Okay, here's the function responsible for allocating the socket, binding it to a port, and all that good stuff. If someone could help me to get this running, I would be super grateful!
Code:
/*
*** net_socket_open ***
allocates an active or passive socket. if the socket is active,
then it connects to the desired host/service/transport. if the
socket is passive, then it binds the socket to the local
service/transport.
*** parameters ***
ap: NET_CONN_PASSIVE for passive , NET_CONN_ACTIVE
for active
host: the host to connect to ( active sockets only , ignored
for passive sockets )
service: the service associated with the desired port, or the
port number represented as a string
transport: the name of the transport protocol to use
qlen: the maximum server request queue length ( passive
sockets only , ignored for active sockets )
portbase: the offset to use in case a privileged port is
requested, but sufficient privileges are not available
*/
struct net_conn* net_conn_alloc( int ap , const char* host , const char* service , const char* transport , int qlen , int portbase )
{
/* pointer to net_socket struct to hold net_conn info */
struct net_conn* c ;
/* allocate a net_conn struct and check it for errors */
if( (c = calloc( 1 , sizeof(struct net_conn) )) == 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "unable to allocate a struct net_conn in net_conn_alloc\n" ) ;
#endif
return( NULL ) ;
}
/* set the active/passive flag for the net_conn */
c->ap = ap ;
/* initialize the endpoint address */
c->sin.sin_family = AF_INET ;
c->sin.sin_addr.s_addr = INADDR_ANY ;
if( c->ap != NET_CONN_PASSIVE && c->ap != NET_CONN_ACTIVE )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "passed an illegal value for ap to net_conn_alloc: %d\n" , c->ap ) ;
#endif
free( c ) ;
return( NULL ) ;
}
/* Map service name to port number */
if( (c->se = getservbyname( service , transport )) )
c->sin.sin_port = htons( ntohs( (u_short) c->se->s_port ) + portbase ) ;
else if( (c->sin.sin_port = htons((u_short)atoi(service))) == 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot map service/port \"%s\" over transport \"%s\" in socket_alloc\n" , service , transport ) ;
#endif
free( c ) ;
return( NULL ) ;
}
if( c->ap == NET_CONN_ACTIVE )
{
/* map the host name to an ip address. allow dotted decimal notation */
if( (c->he = gethostbyname( host )) )
memcpy( &c->sin.sin_addr , c->he->h_addr , c->he->h_length ) ;
else if( (c->sin.sin_addr.s_addr = inet_addr(host)) == INADDR_NONE )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "host \"%s\" cannot be mapped in socket_alloc\n" , host ) ;
#endif
free( c ) ;
return( NULL ) ;
}
}
/* Map transport protocol name to protocol number */
if( (c->pe = getprotobyname( transport )) == 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot map transport \"%s\" to a protocol numer in socket_alloc\n" , transport ) ;
#endif
free( c ) ;
return( NULL ) ;
}
/* Use protocol to choose a socket type */
if( strcmp( transport , "udp" ) == 0 )
c->type = SOCK_DGRAM ;
else if( strcmp( transport , "tcp" ) == 0 )
c->type = SOCK_STREAM ;
else
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "bad transport \"%s\" in socket_alloc\n" , transport ) ;
#endif
free( c ) ;
return( NULL ) ;
}
/* Allocate a socket */
if( (c->socket = socket( PF_INET , c->type , c->pe->p_proto )) < 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot create socket in socket_alloc: %s\n" , strerror( errno ) ) ;
#endif
free( c ) ;
return( NULL ) ;
}
if( c->ap == NET_CONN_ACTIVE )
{
/* connect to the remote host/service */
if( connect( c->socket , (struct sockaddr*)&c->sin , sizeof(c->sin)) < 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot connect to \"%s.%s\" in socket_alloc: %s\n" , host , service , strerror( errno ) ) ;
#endif
free( c ) ;
return( NULL ) ;
}
return( c ) ;
}
else
{
/* bind it to the correct transport/service port */
if( bind( c->socket , (struct sockaddr*) &c->sin , sizeof(c->sin) ) < 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot bind socket to \"%s\" port in socket_alloc: %s\n" , service , strerror( errno ) ) ;
#endif
free( c ) ;
return( NULL ) ;
}
/* set the queue length for the socket connection */
c->qlen = qlen ;
if( c->type == SOCK_STREAM && listen( c->socket , c->qlen ) < 0 )
{
#if defined( NET_CONN_DEBUG )
fprintf( stderr , "cannot listen on port \"%s\" in socket_alloc: %s\n" , service , strerror( errno ) ) ;
#endif
free( c ) ;
return( NULL ) ;
}
return( c ) ;
}
}
That looks like a generic function. If it listens to other ports OK, this function is probably fine. More likely some other case is making a decision to never call this function because it decided it was not going to listen, or something.
Someone will have to do study and learn all this code.
If you get no error and it's not stuck on a system call, my guess is that you're accidentally specifying "udp" since that looks like the only way the function can get past listen without you knowing about it. You should place confirmatory output to show the progression of the function call, e.g. fprintf statements before each of the system calls and before any return statement.
Kevin Barry
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.