Click to See Complete Forum and Search --> : Segmentation Fault with BSD Sockets


julen
04-27-2009, 03:13 PM
Hi!

I am trying to connect two processes using BSD Sockets under Ubuntu using latest gcc compiler.

I do what all the stuff found in Internet tell me to do but I am stuck in an strange segmentation fault. I think is something related with memory management but I can still no see it. It's just happens beforen calling send() method.

Here is the code:

int
Ics::RunOneEvent ()
{
struct sockaddr_in stSockAddr;
int Res;
int SocketFD = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
if (-1 == SocketFD)
{
perror("cannot create socket");
exit(EXIT_FAILURE);
}

//Inicializa memoria.
memset(&stSockAddr, 0, sizeof(stSockAddr));

stSockAddr.sin_family = AF_INET;
stSockAddr.sin_port = htons(1983);
Res = inet_pton(AF_INET, "127.0.0.1", &stSockAddr.sin_addr);

if (0 > Res)
{
perror("error: first parameter is not a valid address family");
close(SocketFD);
exit(EXIT_FAILURE);
}
else if (0 == Res)
{
perror("char string (second parameter does not contain valid ipaddress");
close(SocketFD);
exit(EXIT_FAILURE);
}

if (-1 == connect(SocketFD, (sockaddr*)&stSockAddr, sizeof(stSockAddr)))
{
perror("connect failed");
close(SocketFD);
exit(EXIT_FAILURE);
}

char *code;
strcpy (code,"002;");

puts (code); //I can see the code value but just crash happens here.

int a = send (SocketFD, code, strlen(code), 0);

printf("%d",a); //This value is not printed.

shutdown (SocketFD, SHUT_RDWR);

close (SocketFD);
}

I am pretty newbie in C++ but this is driving me crazy since I wanted to learn about sockets and I did just what every tutorial says. :(

Thank you very much in advance for your advice.

Julen.

drkybelk
04-27-2009, 05:31 PM
well you have a pointer that points into the deep void...

char *code; // <--- this pointer is uninitialised and points somewhere
strcpy (code,"002;"); // here you try to string-copy to this address !!! BAD MOVE !!!



you need to allocate memory to where you can copy, sth like

code = new char[1024]; // now you can strcpy into code


don't forget to free the memory when you don't need it any more


delete [] code;

Danny
04-28-2009, 02:01 AM
...or better yet, allocate the char array statically and avoid the manual memory management mess:

char code[1024]={0};
strcpy (code,"002;");

julen
04-28-2009, 06:57 AM
Thank you very much both!! It worked!!! :-D

Now I have two questions about the code, if you will to answer me and expand my knowledge in C++:

1) Why 1024 positions for the char array? (Maybe because the maximum array length a socket can handle?)

2) I don't understand what is really behind = {0}....

3-Bonus) It's ok to use those sockets calls, but in the C++ developers community is any standard or more used wrapper library to do the same functionality but it's more comprehensive for dummys like me?

Thanks a lot again guys!

Danny
04-28-2009, 07:16 AM
1. some protocols restrict the max number of bytes that can be trasmitted in one shot to this limit, but you have to check the documentation to make sure that this is truly the upper limit.
2. Zero initialization of every byte in the array.
3. There are several non-standard but widely used class libraries such as ACE which disguise the low-level socket API with a higher level OO design. However, it's perfectly OK to use the bare socket API so long as you check every return code, pointer etc.

julen
04-28-2009, 10:18 AM
Thanks Daniel for your explanation. It's really helps me understand my code.

About sockets, I realize that some use strlen() and others use sizeof() to input the size of the payload sent or received via socket. What is the difference?

Best regards.

jonnin
04-28-2009, 11:03 AM
strlen is looking for the first zero in the data stream, which might be bad. If your data is all text, that is fine, but if you had 0x00 the integer sent across the wire (in binary of course), strlen would consider that to be all the data and stop, whereas you need the stuff after the zero!

Sizeof is not a good plan either, really. Sizeof(int) = 32 for example; sizeof is a built in operator that tells you the raw number of bytes that a specific type (user or built in types) has. But it does not tell you anything about a data packet!!! If you had space for 1000 bytes, and you get 53 bytes in the data stream, sizeof cannot provide for you the 53, it can only tell you 1000 (if that, it does not work on pointers).

So, you need to let the socket library tell you how many bytes you got, or, your protocol should tell you the size of the data, typically the first 2-4 bytes represent an integer that tell you how many bytes the packet should have. But if you are not in charge of both ends of the communications, you may have to do something else. Other schemes have terminal sequences (the data stream might always end with "/?>!" or some odd byte pattern). If you did not create the protocol, it should be documented likely there is a marker to tell you this information. If you did create the data streams, simply add this information.