accept() function

Hi! I´m doing my first client/server application.

First I declare program´s variables:
int listener_fd, client_fd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;

I use socket() function to create a new socket:
listener_fd = socket(AF_INET, SOCK_STREAM , 0) , and listener_fd =
3.

Then I call bind() function:
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(7000);
my_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(my_addr.sin_zero), ‘\0’, :sunglasses:;
bind(listener_fd , (struct sockaddr *)&my_addr, sizeof(struct
sockaddr))

Next, I prepare socket to listen():
listen(listener_fd, 10);

Last, wait for client to connect():
sin_size = sizeof(struct sockaddr_in);
client_fd = accept(listener_fd, (struct sockaddr *)&their_addr,
&sin_size)), and client_fd = 0.

When a client connects with the server with connect() function, accept()
function creates a new file descriptor to talk with client.

I use the send() and recv() functions to talk, i.e. : send(client_fd,
“Hello!\n”, 7, 0);


The problem is the message is sent to console and not to client. Then I have
changed the client_fd to 4 (client_fd = 4;), and surprise: server and
client talk!!!
Next, I want to open a file to send it and a segmentation fault (SIGSEGV
signal) is produced.
Why it happens???

Jorge Alonso <jalonso@ain.es> wrote:

Can you post the actual code?


Hi! I’m doing my first client/server application.

First I declare program’s variables:
int listener_fd, client_fd;
struct sockaddr_in my_addr;
struct sockaddr_in their_addr;
int sin_size;

I use socket() function to create a new socket:
listener_fd = socket(AF_INET, SOCK_STREAM , 0) , and listener_fd =
3.

Then I call bind() function:
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(7000);
my_addr.sin_addr.s_addr = INADDR_ANY;
memset(&(my_addr.sin_zero), ‘\0’, > :sunglasses:> ;
bind(listener_fd , (struct sockaddr *)&my_addr, sizeof(struct
sockaddr))

Next, I prepare socket to listen():
listen(listener_fd, 10);

Last, wait for client to connect():
sin_size = sizeof(struct sockaddr_in);
client_fd = accept(listener_fd, (struct sockaddr *)&their_addr,
&sin_size)), and client_fd = 0.

Do you print client_fd at this point? How do you know it is 0?

The problem is the message is sent to console and not to client. Then I have
changed the client_fd to 4 (client_fd = 4;), and surprise: server and
client talk!!!
Next, I want to open a file to send it and a segmentation fault (SIGSEGV
signal) is produced.
Why it happens???

Again, can you post the code? A SIGSEGV generally means you dereferenced
a bad pointer.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Application is formed by several threads. This is fundamental code of thread
(tcpip.c) where the problem happens.
Application opens COM1, COM2 and other files too (in others threads).

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/select.h>
#include <errno.h>

#include “constants.h”
#include “extern.h”
#include “protocol.h”
#include “tcpip.h”

// Note: All variables start with ‘g_’ are application´s global
variables

// ********************** thread´s global variables


struct sockaddr_in their_addr;

// ******************** thread´s functions ******************
int InitSocket(void);
void CommandWait(void);

void *thread_socket(void *pArgs) {
int sin_size;
int nbytes;

if (InitSocket() != 0) {
close(g_listener);
return (void*)1;
}

while(g_bRunSocket) {
sin_size = sizeof(struct sockaddr_in);
if (g_cliente = accept(g_listener, (struct sockaddr
*)&their_addr, &sin_size) == -1) {
printf(“Error en accept\n”);
close(g_listener);
break;
}
printf(“connection server %s:%d\n”,
inet_ntoa(their_addr.sin_addr), ntohs (their_addr.sin_port));
// g_client = 0
g_client = g_listener + 1; // if I del
this line, “OK\n” is sent to console, and not to client. why???
nbytes = send(g_client, “OK\n”, 3, 0);
if (nbytes == -1) printf(“Error en send\n”);
do {
WaitCommand();
}while(g_client != NULL);
}
return 0;
}

int InitSocket(void)
{
struct sockaddr_in my_addr;
int yes = 1;

if ((g_listener = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
perror(“Error en socket\n”);
return 1;
}
// g_listener = 3
if (setsockopt(g_listener, SOL_SOCKET, SO_REUSEADDR, &yes,
sizeof(int)) == -1) {
perror(“Error en setsockopt\n”);
return 1;
}
my_addr.sin_family = AF_INET;
my_addr.sin_port = htons(PORT);
//communication port (7000)
my_addr.sin_addr.s_addr = htonl(INADDR_ANY); //my IP
memset(&(my_addr.sin_zero), ‘\0’, :sunglasses:;
if (bind(g_listener, (struct sockaddr *)&my_addr, sizeof(struct
sockaddr)) == -1) {
perror(“Error en bind\n”);
return 1;
}
if (listen(g_listener, BACKLOG) == -1) {
perror(“Error en listen\n”);
return 1;
}
return 0;
}

void CommandWait(void) {
int nbytes;
unsigned char buf[256];
BYTE i, chk;

nbytes = recv(g_client, buf, 256, 0);
if (nbytes <= 0) {
close(g_client);
g_client = NULL;
}
else {
if ((nbytes == 5) || (nbytes == 22) || (nbytes == 25)) {
if(buf[0] == ‘$’ && buf[nbytes-1] == ‘#’) {
chk = 0;
for (i=1;i<nbytes-2;i++) chk = chk + buf_;
if (buf[nbytes-2] == chk) {
if (buf[1] == ‘C’ && buf[2] == ‘F’) Config(1);
else if (buf[1] == ‘G’ && buf[2] == ‘O’)
Run(1);
else if (buf[1] == ‘W’ && buf[2] == ‘P’) {
if (CONFIG) ModifyParam(buf, 1);
}
else if (buf[1] == ‘R’ && buf[2] == ‘P’)
ReadParam(1);
else if (buf[1] == ‘L’ && buf[2] == ‘F’)
ListFiles(1);
else if (buf[1] == ‘D’ && buf[2] == ‘F’)
DelFile(buf);
else if (buf[1] == ‘D’ && buf[2] == ‘W’)
DownloadFile(buf, 1);
else if (buf[1] == ‘S’ && buf[2] == ‘T’)
Stop(1);
}
else {
printf(“checksum´s error!\n”);
}
}
else {
printf(“packet´s error!!!\n”);
}
}
}


// This function belongs to protocol.c
int DownloadFile(char* c, BOOL bTransmition) {
char szFile[20];
int fdw;
int size_read;
char buffer[512];
char szInit[] = “$SF”;
char szEnd[] = “OK#”;
char szError[] = “ER#”;

strcpy(szFile, “/tmp/”);
strncat(szFile, &c[3], CHARSFILE);
fdw = open(szFile, O_RDONLY); //here SIGSEGV signal is
produced!!!
if (fdw != NULL) {
//Send data init
if (bTransmition == 0) write(g_Com1, szInicio, 3);
else send(g_client, szInit, 3, 0);
//Send data file
do {
size_read = read(fdw, buffer, sizeof(buffer));
if (size_read == -1) {
//send data error
if (bTransmition == 0) write(g_Com1, szError, 3);
else send(g_client, szError, 3, 0);
return 1;
}
if (bTransmition == 0) write(g_Com1, buffer, size_read);
else send(g_client, buffer, size_read, 0);
}while (size_read == sizeof(buffer));
//send data end
if (bTransmition == 0) write(g_Com1, szFin, 3);
else send(g_client, szEnd, 3, 0);
close(fdw);
}
return 0;
}_

Better yet, do the assignment outside of the conditional. I.E.
g_client = accept();
if( g_client == -1 )

There is less confusion to look at it and it is easier to examine the
result of the function call with a debugger before the branch is taken.


David Gibbs <dagibbs@qnx.com> wrote:
DG > Jorge Alonso <jalonso@ain.es> wrote:

if (g_cliente = accept(g_listener, (struct sockaddr
*)&their_addr, &sin_size) == -1) {

DG > This is exactly what I thought the problem is. That line is saying:

DG > if (g_cliente = ( accept(…) == -1 ) ) {

DG > That is, g_cliente is given the value of the test. Which is false, so
DG > g_cliente ends up 0, exactly as you said. You need to bracket
DG > it like:

DG > if ( (g_cliente = accept(g_listener, (struct sockaddr
DG > *)&their_addr, &sin_size)) == -1) {

DG > -David
DG > –
DG > QNX Training Services
DG > http://www.qnx.com/support/training/
DG > Please followup in this newsgroup if you have further questions.


Bill Caroselli – Q-TPS Consulting
1-(708) 308-4956 <== Note: New Number
qtps@earthlink.net

Jorge Alonso <jalonso@ain.es> wrote:

if (g_cliente = accept(g_listener, (struct sockaddr
*)&their_addr, &sin_size) == -1) {

This is exactly what I thought the problem is. That line is saying:

if (g_cliente = ( accept(…) == -1 ) ) {

That is, g_cliente is given the value of the test. Which is false, so
g_cliente ends up 0, exactly as you said. You need to bracket
it like:

if ( (g_cliente = accept(g_listener, (struct sockaddr
*)&their_addr, &sin_size)) == -1) {

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Jorge Alonso <jalonso@ain.es> wrote:

// This function belongs to protocol.c
int DownloadFile(char* c, BOOL bTransmition) {
char szFile[20];
int fdw;
int size_read;
char buffer[512];
char szInit[] = “$SF”;
char szEnd[] = “OK#”;
char szError[] = “ER#”;

strcpy(szFile, “/tmp/”);
strncat(szFile, &c[3], CHARSFILE);

How long is the filename passed in? How big is the value CHARSFILE?

fdw = open(szFile, O_RDONLY); //here SIGSEGV signal is
produced!!!

I’d guess you’ve run off the end of szFile in filling it, then when more
stuff gets pushed on the stack to call open() it overwrites/trashes
the NULL byte at the end of szFile, and wanders into invalid stack
when it tries to use it.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Bill Caroselli <qtps@earthlink.net> wrote:

Better yet, do the assignment outside of the conditional. I.E.
g_client = accept();
if( g_client == -1 )

There is less confusion to look at it and it is easier to examine the
result of the function call with a debugger before the branch is taken.

Yeah, but that’s so un-C-style-like. :slight_smile:

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Hi David…

…but very safe…! I’m with Bill on this one.

Regards…

Miguel.

David Gibbs wrote:

Bill Caroselli <> qtps@earthlink.net> > wrote:

Better yet, do the assignment outside of the conditional. I.E.
g_client = accept();
if( g_client == -1 )


There is less confusion to look at it and it is easier to examine the
result of the function call with a debugger before the branch is taken.


Yeah, but that’s so un-C-style-like. > :slight_smile:

-David

I have verified the filename (it is correct), but I will find out if after
calling to open() the last byte of filename is Null.

I try to probe this the next week, because I´m on a trip all the week.

Thanks, Jorge.

“David Gibbs” <dagibbs@qnx.com> escribió en el mensaje
news:bpl8m8$e18$1@nntp.qnx.com

Jorge Alonso <> jalonso@ain.es> > wrote:

// This function belongs to protocol.c
int DownloadFile(char* c, BOOL bTransmition) {
char szFile[20];
int fdw;
int size_read;
char buffer[512];
char szInit[] = “$SF”;
char szEnd[] = “OK#”;
char szError[] = “ER#”;

strcpy(szFile, “/tmp/”);
strncat(szFile, &c[3], CHARSFILE);

How long is the filename passed in? How big is the value CHARSFILE?

fdw = open(szFile, O_RDONLY); //here SIGSEGV signal is
produced!!!

I’d guess you’ve run off the end of szFile in filling it, then when more
stuff gets pushed on the stack to call open() it overwrites/trashes
the NULL byte at the end of szFile, and wanders into invalid stack
when it tries to use it.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

Jorge Alonso <jalonso@ain.es> wrote:

I have verified the filename (it is correct).

I didn’t say the filename was wrong – I asked about how long it was,
and how big the value CHARSFILE was.

but I will find out if after
calling to open() the last byte of filename is Null.

If you sigsegv in open(), then it will be tricky to check after
the open() call.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

I have tested two problems: accept() function it´s ok :wink:, but open() call
no :frowning:.

I try to find out the last character´s value of szFile after open()
call, but I don´t know, because the program stop. I hope it helps you.

#define CHARSFILE = 14

The filename have 19 characters, and it is composed of:
“/tmp/” + name (14 characters) + NULL character ==> 20
characters (p.e. “/tmp/PV0_021203.dat”)

Note: I have found, before open() call, that c is
“$DWPV0_021203.dat\301#\2624\260” , but c must be “$DWPV0_021203.dat#”. Can
it affect to anything?

Jorge Alonso <jalonso@ain.es> wrote:
JA > I have tested two problems: accept() function its ok :wink:, but open() call
JA > no :frowning:.

JA > I try to find out the last characters value of szFile after open()
JA > call, but I dont know, because the program stop. I hope it helps you.

JA > #define CHARSFILE = 14

JA > The filename have 19 characters, and it is composed of:
JA > “/tmp/” + name (14 characters) + NULL character ==> 20
JA > characters (p.e. “/tmp/PV0_021203.dat”)

JA > Note: I have found, before open() call, that c is
JA > “$DWPV0_021203.dat\301#\2624\260” , but c must be “$DWPV0_021203.dat#”. Can
JA > it affect to anything?

Hi. This is just a guess. If I’m off base, sorry for interrupting.

Does your filename include international characters? If so your 19
characters (20 with the null) may actuallt be more bytes than that.

Try increasing the size of your filename array.

Bill Caroselli <qtps@earthlink.net> wrote:

Jorge Alonso <> jalonso@ain.es> > wrote:
JA > I have tested two problems: accept() function its ok > :wink:> , but open() call
JA > no > :frowning:> .

JA > I try to find out the last characters value of szFile after open()
JA > call, but I dont know, because the program stop. I hope it helps you.

JA > #define CHARSFILE = 14

JA > The filename have 19 characters, and it is composed of:
JA > “/tmp/” + name (14 characters) + NULL character ==> 20
JA > characters (p.e. “/tmp/PV0_021203.dat”)

JA > Note: I have found, before open() call, that c is
JA > “$DWPV0_021203.dat\301#\2624\260” , but c must be “$DWPV0_021203.dat#”. Can
JA > it affect to anything?

Hi. This is just a guess. If I’m off base, sorry for interrupting.

Does your filename include international characters? If so your 19
characters (20 with the null) may actuallt be more bytes than that.

strncat() shouldn’t care, though. And that funny \301 is after
the 14th character.

Try increasing the size of your filename array.

I still think this is a good idea. Also, what happens if you do a
printf("%s\n", szfile);
just before calling open. If we crash in printf() instead of open(),
we’re pretty sure you’ve got your math wrong somewhere on those
lengths.

-David

QNX Training Services
http://www.qnx.com/support/training/
Please followup in this newsgroup if you have further questions.

David Gibbs <dagibbs@qnx.com> wrote:
DG > Bill Caroselli <qtps@earthlink.net> wrote:

Try increasing the size of your filename array.

DG > I still think this is a good idea. Also, what happens if you do a
DG > printf("%s\n", szfile);
DG > just before calling open. If we crash in printf() instead of open(),
DG > we’re pretty sure you’ve got your math wrong somewhere on those
DG > lengths.

DG > -David

If he has over run the cahr array he probibly clobbered whatever comes
next in memory. It may of may not be exhibited by a printf().
My guess is not.

What I would add is:
printf( “strlen() of filename = %d\n”, strlen( szfile ) );

BC > If he has over run the cahr array he probibly clobbered whatever comes

Make that “char aeeay”.

Bill Caroselli <qtps@earthlink.net> wrote:

BC > BC > If he has over run the cahr array he probibly clobbered whatever comes

BC > Make that “char aeeay”.

LOL Oh, never mind!

The filename´s characters always are:
PV + channel number + “_” + date + “.dat”
p.e. : PV1_041203.dat

I have tested to show the filename (and your length too) with printf()
function, and it´s OK. Then I think the problem isn´t in filename. In any
case I have also increased the array´s size and it does not work well.

As I have commented to you I use the same function to send data (file´s
information) by serial port or tcpip. When I try to send data by serial port
I do not have any problem.

Can I use any function on file that is not open()?

Note: What is aeeay??? I don´t understand the lasts emails:(

Jorge Alonso <jalonso@ain.es> wrote:

JA > Note: What is aeeay??? I dont understand the lasts emails:(

Sorry. It was a typo. It was supposed to be “array”.
You may notice that the e is next to the r on US keyboards.

I have already found out the problem, but I still don´t know why.

You must put attention in the change I do :slight_smile:.

int DownloadFile(char* c, BOOL bTransmition) {
char szFile[20];
int fdw;
int size_read;
char buffer[100]; // I change this line (before it was:
char buffer[512]; )
char szInit[] = “$SF”;
char szEnd[] = “OK#”;
char szError[] = “ER#”;

strcpy(szFile, “/tmp/”);
strncat(szFile, &c[3], CHARSFILE);
fdw = open(szFile, O_RDONLY);
if (fdw != NULL) {
//Send data init
if (bTransmition == 0) write(g_Com1, szInicio, 3);
else send(g_client, szInit, 3, 0);
//Send data file
do {
size_read = read(fdw, buffer, sizeof(buffer)); //The
problem was in this line because the size of array was too great.
if (size_read == -1) {
//send data error
if (bTransmition == 0) write(g_Com1, szError, 3);
else send(g_client, szError, 3, 0);
return 1;
}
if (bTransmition == 0) write(g_Com1, buffer, size_read);
else send(g_client, buffer, size_read, 0);
}while (size_read == sizeof(buffer));
//send data end
if (bTransmition == 0) write(g_Com1, szFin, 3);
else send(g_client, szEnd, 3, 0);
close(fdw);
}
return 0;
}