Problem implementing sockets with C++

Problem implementing sockets with C++

Post by Haka » Tue, 01 Sep 2009 03:26:16



Did anyone try implementing the code for C++ sockets posted by Rob
Tougher in the Linuz Gazette? The files are online over at
http://www.yqcomputer.com/
quite easy to follow.

I tried it, but I get a segmentation fault every time that I run it. It
occurs at the first call to accept in the server main application. Gdb
does not give me this information about the sock parameter.

print sock
$3 = (Server &) @0xbf8822f0: {<Socket> = {_vptr.Socket = 0x80499d8,
m_sock = -1, m_addr = {sin_family = 0, sin_port = 0, sin_addr = {
s_addr = 0},
sin_zero = "\000\000\000\000\000\000\000"}}, <No data fields>}

What goes wrong? I feel that I did very few changes of the code in the
magazine. It seems odd that it does not even enter the accept routine in
the superclass.

Thanks.



--
Newsoffice.de - Die Onlinesoftware zum Lesen und Schreiben im Usenet
Die Signatur lt sich nach Belieben anpassen ;-)
 
 
 

Problem implementing sockets with C++

Post by Lo Domaig » Tue, 01 Sep 2009 04:41:31

Hello,


<snip>

Ok. I believe there is an error in Socket.cpp:

bool Socket::accept ( Socket& new_socket ) const
{
int addr_length = sizeof ( m_addr );
new_socket.m_sock = ::accept ( m_sock, ( sockaddr * ) &m_addr,
( socklen_t * ) &addr_length );

--> shoudn't it be:
new_socket.m_sock = ::accept ( m_sock, ( sockaddr * )
&new_socket.m_addr, ( socklen_t * ) &addr_length );
....
}

HTH,
Lo.
My Blog: http://www.yqcomputer.com/

"A computer lets you make more mistakes faster than any invention in
human historyith the possible exceptions of handguns and tequila."
-- Mitch Radcliffe

 
 
 

Problem implementing sockets with C++

Post by Haka » Tue, 01 Sep 2009 19:12:37


Thanks for that. However, the code does not even get into that routine.
I get a segmentation fault just before entering there no matter what.
This is just very odd. Anyone who has done this and know what I should
do?



--
Newsoffice.de - Die Onlinesoftware zum Lesen und Schreiben im Usenet
Die Signatur lt sich nach Belieben anpassen ;-)
 
 
 

Problem implementing sockets with C++

Post by Rainer Wei » Tue, 01 Sep 2009 19:20:53

Hakan < XXXX@XXXXX.COM > writes:

[...]


[...]


Fix the faulting memory access? gdb will tell you the exact line of
code where the fault happens or at least provide a useful backtrace,
should you be passing invalid parameters to a library routine which
then segfaults because of that. If you really don't have any idea
regarding the 'why' after knowing the 'where', try posting the code
which causes the problem instead of referring to something else which
has presumably been tested before it was published and stating that
you changed that 'somehow'. Nobody here is telepathic and 'wild
guesses' are a really bad debugging methodology.
 
 
 

Problem implementing sockets with C++

Post by Haka » Tue, 01 Sep 2009 19:44:37


This is where the error keeps occurring:

void Server::accept ( Server& sock )
{
if ( !(Socket::accept ( (Socket&) sock ))) (this line)

called by

Server runserv ( port );

while ( true )
{

Server new_sock;
runserv.accept ( new_sock ); (called from here)

}

Socket created as:

Socket::Socket() :
m_sock(-1)
{
/*Create socket structure*/
memset ( &m_addr,
0,
sizeof ( m_addr ) );

}

(Server is subclass of socket)

Han

--
Newsoffice.de - Die Onlinesoftware zum Lesen und Schreiben im Usenet
Die Signatur lt sich nach Belieben anpassen ;-)
 
 
 

Problem implementing sockets with C++

Post by Ben Bacari » Tue, 01 Sep 2009 20:06:36

Hakan < XXXX@XXXXX.COM > writes:


I went and had a look, but it is possible that you are not running the
code presented in the magazine because it won't compile (at least on
my system). How did you correct the errors? I made minimal
corrections[1] and do not get a segmentation fault.

Of course that does not mean the code is correct but it means it is
hard to help. What, exactly, is the code you are running?

<snip>

[1] Both main functions are defined to take int argv[] rather than
char *argv[], and a couple of files need to #include <iostream>.

--
Ben.
 
 
 

Problem implementing sockets with C++

Post by Haka » Wed, 02 Sep 2009 19:44:56


I did some changes mostly to the send and receive routines to fir the
requirements of my aplpication. However, the error occurs before they
are even invoked. Here is the code that just keeps giving me
segmentation faults:

From main:

Server runserv ( port );

while ( true )
{

Server new_sock;
runserv.accept ( new_sock );


Constructor in socket class, superclass to server:

Socket::Socket() :
m_sock(-1)
{
/*Create socket structure*/
memset ( &m_addr,
0,
sizeof ( m_addr ) );

}



void Server::accept ( Server& sock )
{
if ( !(Socket::accept ( (Socket&) sock ))) This line gives
segmentation fault.



Thanks.

--
Newsoffice.de - Die Onlinesoftware zum Lesen und Schreiben im Usenet
Die Signatur lt sich nach Belieben anpassen ;-)
 
 
 

Problem implementing sockets with C++

Post by Lo Domaig » Wed, 02 Sep 2009 21:07:38

Hello Han,


Chances are that your changes are triggering the problem. The code
given in Linux Gazette is perhaps not perfect, but I couldn't
reproduce any SIGSEGV...

I am afraid that we won't be able to help without any further
information. We need to know what your changes are exactly. Or (even
better), we need a minimalistic program that compiles and runs, and
that shows the behavior. Otherwise we're quite in the dark.

Cheers,
Lo
My Blog: http://www.yqcomputer.com/

"They have computers, and they may have other weapons of mass
destruction." -- Janet Reno
 
 
 

Problem implementing sockets with C++

Post by scot » Thu, 03 Sep 2009 02:25:42

=?ISO-8859-1?Q?Lo=EFc_Domaign=E9?= < XXXX@XXXXX.COM > writes:

At the very least provide a stack traceback 'bt', the 'info registers' output and
a disassembly of the routine in which the failure occured 'disass function'.

The code fragements posted are completely useless.

scott
 
 
 

Problem implementing sockets with C++

Post by Haka » Thu, 03 Sep 2009 09:11:04

cott Lurndal wrote:



OK. I'll give you everything at once. I hope that it will be clear.

Socket class: as in magazine with exceptions:

bool Socket::send ( char* schars ) const
{
std::string s=schars;
int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
if ( status == -1 )
{
return false;
}
else
{
return true;
}
}


int Socket::recv ( char* schars ) const
{
char buf [ MAXRECV + 1 ];

/*s = "";*/

memset ( buf, 0, MAXRECV + 1 );

int status = ::recv ( m_sock, buf, MAXRECV, 0 );

if ( status == -1 )
{
std::cout << "status == -1 errno == " << errno << " in
Socket::recv\n";
return 0;
}
else if ( status == 0 )
{
return 0;
}
else
{
schars = buf;
return status;
}
}

Server: as in magazine with exceptions:


void Server::sendString (char* s)
{

if ( ! Socket::send ( s ) )
{
std::cout << "Could not write to socket.";
}


}


int Server::receiveString (char* s)
{

if ( ! Socket::recv ( s ) )
{
return -1;
}
else
{
return 1;
}
}

void Server::accept ( Server& sock )
{
if ( !(Socket::accept ( (Socket&) sock )))
{
std::cout<<"Could not accept socket.";
}
else
{
char bufchars[MAXRECV+1];
while (this->receiveString(bufchars))
{

}
}

Server main program:

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

int port;
if (argc>0)
{
port=(int) argv[0];
}
else
{
port=2000;
}

// Create the socket
Server runserv ( port );

while ( true )
{

Server new_sock;
runserv.accept ( new_sock );

}


return 0;
}

Program gets seg fault on first call to accept
(runserv.accept(new_sock)).

Stack trace (where):

#0 0x08048fb8 in Server::accept (this=0xbf858fe0, sock=@0xbf858fc0)
at Server.cpp:64
#1 0x080497d5 in main (argc=1, argv=0xbf8590a4) at servmain.cpp:24

info registers:


eax 0xbf858fe0 -1081765920
ecx 0x0 0
edx 0x0 0
ebx 0x949ff4 9740276
esp 0xbc8a9ee8 0xbc8a9ee8
ebp 0xbf858f88 0xbf858f88
esi 0xbf8590a4 -1081765724
edi 0xbf859030 -1081765840
eip 0x8048fb8 0x8048fb8
eflags 0x10296 66198
cs 0x73 115
ss 0x7b 123
ds 0x7b 123
es 0x7b 123
fs 0x0 0
gs 0x33 51

disass accept

0x08048fac <_ZN6Server6acceptERS_+0>: push %ebp
0x08048fad <_ZN6Server6acceptERS_+1>: mov %esp,%ebp
0x08048faf <_ZN6Server6acceptERS_+3>: sub $0x2faf098,%esp
0x08048fb5 <_ZN6Server6acceptERS_+9>: sub $0x8,%esp
0x08048fb8 <_ZN6Server6acceptERS_+12>: pushl 0xc(%ebp)
0x08048fbb <_ZN6Server6acceptERS_+15>: pushl 0x8(%ebp)
0x08048fbe <_ZN6Server6acceptERS_+18>: call 0x804941e
<_ZN6Socket6acceptERS_>
0x08048fc3 <_ZN6Server6acceptERS_+23>: add $0x10,%esp
0x08048fc6 <_ZN6Server6acceptERS_+26>: test %al,%al
0x08048fc8 <_ZN6Server6acceptERS_+28>: jne 0x8048fe1
<_ZN6Server6acceptERS_+53>
0x08048fca <_ZN6Server6acceptERS_+30>: sub $0x8,%esp
0x08048fcd <_ZN6Server6acceptERS_+33>: push $0x8049997
0x08048fd2 <_ZN6Server6acceptERS_+38>
 
 
 

Problem implementing sockets with C++

Post by Ben Bacari » Thu, 03 Sep 2009 10:12:24

Hakan < XXXX@XXXXX.COM > writes:



Programming is a matter of details. A comma in the wrong place could
be your problem.


This is wrong. It may be what is causing trouble, it may not be.
Setting schars (a local variable) has no effect on the buffer passing
in.


You have changed the name of the class. Can we be sure that no error
crept in when you did this edit?


Why this change?


This does not do what you think it does.


You really have to post the actual code that is causing the trouble.

--
Ben.
 
 
 

Problem implementing sockets with C++

Post by Haka » Thu, 03 Sep 2009 13:52:15


schars is the parameter to the routine and not a local variable. The
only difference from the original code is that it is a char* rather than
a std: string&. What do you mean here?



Not that I can see. Besides, I would have expected such problems to
be caught by the compiler. Why would they not be?



Since the fault occurs right there I fekt that I should try different
options. The error came in the original version as well. That did not
seem to make a change to the outcome.


That is what I did.

I should have told you also that I dropped SocketException and all
references to it.

Han

--
Newsoffice.de - Die Onlinesoftware zum Lesen und Schreiben im Usenet
Die Signatur lt sich nach Belieben anpassen ;-)
 
 
 

Problem implementing sockets with C++

Post by Rainer Wei » Thu, 03 Sep 2009 17:29:48

Hakan < XXXX@XXXXX.COM > writes:

schars _is_ a local variable which contains a copy of the argument
value. Assigning to a std::string& would have caused the contents of
the buffer to be copied into the string. Your assignment just changes
the value of the local pointer variable to point to a local array of
char.

[...]


You posted some fragments of that, but nothing which anyone could
compile, test and debug. There is at least one serious error in the
posted code:


int port;
if (argc>0)
{
port=(int) argv[0];
}

argv[0] is a char * which points to the 'first argument' of execve and
this is usually the program name. The first user-supplied argument is
argv[1]. The cast converts the value of the pointer to the program
name to int. This will likely even be a negative value. If you call
this manually using the shell argc > 0 will always be true. What you
likely wanted (minus any input validation etc) would be:

if (argc > 1) port = atoi(argv[1])

If the user supplied an argument, convert the argument string to an
int (not its address) and assign the resulting value to port.
The first argument must be a string representation of a number between
1 and 65535 for this to make any sense ('ports' are 16-bit numbers).
 
 
 

Problem implementing sockets with C++

Post by Haka » Thu, 03 Sep 2009 18:55:47

ainer Weikusat wrote:









OK. I have now made some changes by your recommendations, but keep
getting the same error. Here is the new code for the server side as
three cpp files :

Socket.cpp:

// Implementation of the Socket class.


#include "Socket.h"
#include <string.h>
#include <errno.h>
#include <fcntl.h>
#include <iostream>

/*Constructor*/
Socket::Socket() :
m_sock(-1)
{
/*Create socket structure*/
memset ( &m_addr,
0,
sizeof ( m_addr ) );

}



/*Destructor*/
Socket::~Socket()
{
if ( is_valid() )
::close ( m_sock );
}

/*Open new socket*/
bool Socket::create()
{
/*Internet socket type,streaming socket,default protocol*/
m_sock = socket ( AF_INET,
SOCK_STREAM,
0 );

if ( ! is_valid() )
return false;

/*Specify that all ports should be open and not temporarily locked
after bind attempt*/
int on = 1;
if ( setsockopt ( m_sock, SOL_SOCKET, SO_REUSEADDR, ( const char* )
&on, sizeof ( on ) ) == -1 )
return false;


return true;

}


/*Bind socket to specified port*/
bool Socket::bind ( const int port )
{

if ( ! is_valid() )
{
return false;
}


/*Berkeley API socket data structure*/
m_addr.sin_family = AF_INET;
m_addr.sin_addr.s_addr = INADDR_ANY;
m_addr.sin_port = htons ( port );

int bind_return = ::bind ( m_sock,
( struct sockaddr * ) &m_addr,
sizeof ( m_addr ) );


if ( bind_return == -1 )
{
return false;
}

return true;
}


bool Socket::listen() const
{
if ( ! is_valid() )
{
return false;
}

int listen_return = ::listen ( m_sock, MAXCONNECTIONS );


if ( listen_return == -1 )
{
return false;
}

return true;
}


bool Socket::accept ( Socket& new_socket )
{
int addr_length = sizeof ( m_addr );
new_socket.m_sock = ::accept ( m_sock, ( sockaddr * )
&new_socket.m_addr, ( socklen_t * ) &addr_length );

if ( new_socket.m_sock <= 0 )
return false;
else
return true;
}


bool Socket::send ( char* schars ) const
{
std::string s=schars;
int status = ::send ( m_sock, s.c_str(), s.size(), MSG_NOSIGNAL );
if ( status == -1 )
{
return false;
}
else
{
return true;
}
}


int Socket::recv ( char* schars ) const
{
char buf [ MAXRECV + 1 ];

/*s = "";*/

int status = ::recv ( m_sock, buf, MAXRECV, 0 );

if ( status == -1 )
{
std::cout << "status == -1 errno == " << errno << " in
Socket::recv\n";
return 0;
}
else if ( status == 0 )
{
return 0;
}
else
{
memcpy(schars,buf,status);
return status;
}
}


bool Socket::connect ( const std::string host, const int port )
{
if ( ! is_valid() ) return false;

m_addr.sin_family = AF_INET;
m_addr.sin_port = htons ( port );

int status = inet_pton ( AF_INET, host.c_str(), &m_addr.sin_addr );

if ( errno == EAFNOSUPPORT ) return false;

status = ::connect ( m_sock, ( sockaddr * ) &m_addr, sizeof ( m_addr )
);

if ( status == 0 )
return true;
else
return false;
}

Server.cpp:

// Implementation of the ServerSocket class

#include "Server.h"
#include "Client.h"
#include <iostream>
#include <string>

Server::Server ( int port )
{
if ( ! Socket::create() )
{
 
 
 

Problem implementing sockets with C++

Post by Ben Bacari » Thu, 03 Sep 2009 23:32:25

Hakan < XXXX@XXXXX.COM > writes:
<snip>

No. This is some of the code. Please (last time) post actual
compilable code. We can't be sure what is in all the other files and
even if you have given all the edits in your various messages, do you
expect people to go though them all apply your changes by hand just to
get the same source that you are having problems with? All you need
do is post the full code.

<snip incomplete server code>
--
Ben.