473,396 Members | 2,050 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,396 software developers and data experts.

socket connection problem

In my project, I have successfully opened a sock_stream style socket
connection between two processes and am trying to send 'buffer' to a
connected client, 'fd'.

The following code works just fine.

void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
}

But, obviously, it is not sending the desired string.

The following code does not work.

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
strcpy(buf, buffer);
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

I'm sure that this very simple code is horrifying to any C programmer,
but I am not a C programmer, I'm just a hack trying to get something
finished. All of the stcpy stuff was done because the connected
client I mentioned is very picky about messages being terminated by a
null character.

Any suggestions as to why the string in the function parameter would
cause a problem, whereas the string declared in the function does not
would be greatly appreciated. I welcome any other questions about my
situation (I'm sure I have forgotten something important), but I would
like to avoid questions about the client, as it is not written in C++
and is therefore off-topic. Suffice to say, it has been tested with
other hosts and works just fine. I am 99% sure that the problem is
with the host, not the client.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #1
11 2881
go****@jeffish.org (Jeff Crouse) wrote:
In my project, I have successfully opened a sock_stream style socket
connection between two processes and am trying to send 'buffer' to a
connected client, 'fd'.

The following code works just fine.

void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
}

But, obviously, it is not sending the desired string.

The following code does not work.

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
strcpy(buf, buffer);
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

I'm sure that this very simple code is horrifying to any C programmer,
but I am not a C programmer, I'm just a hack trying to get something
finished. All of the stcpy stuff was done because the connected
client I mentioned is very picky about messages being terminated by a
null character.

Any suggestions as to why the string in the function parameter would
cause a problem, whereas the string declared in the function does not
would be greatly appreciated. I welcome any other questions about my
situation (I'm sure I have forgotten something important), but I would
like to avoid questions about the client, as it is not written in C++
and is therefore off-topic. Suffice to say, it has been tested with
other hosts and works just fine. I am 99% sure that the problem is
with the host, not the client.


Try this:
#include <iostream>
using namespace std;

int main() {
char message[] = "This is a message from the front.";
char* buf = message;
cout << sizeof( message ) << endl;
cout << sizeof( buf ) << endl;
cout << strlen( message ) << endl;
cout << strlen( buf ) << endl;
}

The output of the above should point you in the right direction.
Jul 19 '05 #2
Jeff Crouse wrote:

Please don't cross-post to moderated groups. It prevents the message
from reaching non-moderated groups in a timely manner. I've removed
comp.lang.c++.moderated from the cross-post list.
In my project, I have successfully opened a sock_stream style socket
connection between two processes and am trying to send 'buffer' to a
connected client, 'fd'.
Note that sockets are not part of standard C++ and are not topical here.

The following code works just fine.

void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
Are you quite sure that write() will set errno? If not, you'd better
first set errno to 0, then test it afterward and only use perror if
errno is non-0.

write() is not a standard function, so we can't say much about it here.
}

But, obviously, it is not sending the desired string.

The following code does not work.

void Macsock::writeData(char *buffer, int fd)
Are you sure const char *buffer would not be better?
{
char buf[strlen(buffer)];
Array sizes must be compile-time constants. Even if this worked, the
array is not large enough for the string you want to copy into it.
strcpy(buf, buffer);
Because 'buf' is too small, this will overwrite memory you don't own,
causing undefined behavior (probably crashing your program or corrupting
data).
buf[sizeof(buf)] = '\0';
The indices for 'buf' (if buf were properly declared) go from 0 to
sizeof(buf)-1, so you are writing past the end of the array here. That
causes undefined behavior. This is pretty basic C++ array stuff - if you
don't understand it, you'd better return to studying for a while before
you attempt to use arrays or do anything non-trivial with the language.

And here's a question: Why are you attempting to copy the array at all?
You could probably just pass in the original - I'm guessing write won't
change it.
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

I'm sure that this very simple code is horrifying to any C programmer,
but I am not a C programmer, I'm just a hack trying to get something
finished. All of the stcpy stuff was done because the connected
client I mentioned is very picky about messages being terminated by a
null character.
Well, in the second example you aren't even attempting to send the null
character, as far as I can tell. You have a char array long enough for
the string but not the null terminator. Then you send using sizeof(buf)
as the size argument (presumably - I'm only guessing since you use a
non-standard function). That has no chance of sending a null character,
which was written past the end of the buf array (maybe - undefined
behavior, so who knows what actually happened?).

Any suggestions as to why the string in the function parameter would
cause a problem, whereas the string declared in the function does not
would be greatly appreciated.
I'm sure it has a lot to do with the use of illegal broken code... It
shouldn't even compile.
I welcome any other questions about my
situation (I'm sure I have forgotten something important), but I would
like to avoid questions about the client, as it is not written in C++
and is therefore off-topic.
Sockets are off-topic, also.
Suffice to say, it has been tested with
other hosts and works just fine. I am 99% sure that the problem is
with the host, not the client.


You mean the code you post? Uh, yeah, I'd say there's some problems with it.

Why are you using C-style arrays anyway? If you had used std::string
instead, pretty much all of your problems would have magically
disappeared. But it would still be a good idea for you to review how
arrays work to avoid problems in the future.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

Jul 19 '05 #3
In article <50**************************@posting.google.com >, Jeff
Crouse <go****@jeffish.org> writes
In my project, I have successfully opened a sock_stream style socket
connection between two processes and am trying to send 'buffer' to a
connected client, 'fd'.

The following code works just fine.

void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
}

But, obviously, it is not sending the desired string.

The following code does not work.

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
The number of elements (chars in this case) must be known at compile
time as C++ and C are both statically typed languages. strcpy(buf, buffer);
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

I'm sure that this very simple code is horrifying to any C programmer,
but I am not a C programmer, I'm just a hack trying to get something
finished. All of the stcpy stuff was done because the connected
client I mentioned is very picky about messages being terminated by a
null character.


Actually a C programmer would take one look, note the :: and ignore the
rest because it isn't C. A C++ programmer sees everything else and
immediately wonders why a member function of Macsock is being defined
with an attempt at writing pure C.

Are you responsible for the Macsock class? If so you need to find help
from someone who understands the fundamentals of class design. If not
you need to throw it away and find a good implementation. Frankly the
above code is so far from reasonable C++ in both design and
implementation that the writer of it needs to first learn about the
available tools provided by C++ (std::string, std::fstream etc.) before
attempting a redesign and fresh implementation. Alternatively you need
to find a good third party implementation of a socket class that meets
your needs.
--
Francis Glassborow ACCU
64 Southfield Rd
Oxford OX4 1PA +44(0)1865 246490
All opinions are mine and do not represent those of any organisation
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #4
Jeff Crouse wrote in news:50afaa52.0309051151.620292a8
@posting.google.com:

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
This is 1 to short.
strcpy(buf, buffer);
You just wrote buffer and its terminating '\0' to the buf
buf[sizeof(buf)] = '\0';
strcpy() just did this, and buf[ sizeof(buf) ] is 1 beyond
the end of buf. All bets are now off!
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

I'm sure that this very simple code is horrifying to any C programmer,
but I am not a C programmer, I'm just a hack trying to get something
finished. All of the stcpy stuff was done because the connected
client I mentioned is very picky about messages being terminated by a
null character.


void Macsock::writeData(char *buffer, int fd)
{
if( write( fd, buffer, strlen( buffer ) + 1 ) < 0 )
perror("writing on stream socket");
}

strlen() counts the nuber of char before it finds a '\0'. So
if buffer doesn't have one the above will not do what you want.
void Macsock::writeData(char *buffer, size_t size, int fd)
{
char buf[ size + 1 ];
strncpy( buf, buffer, size );
buf[ size ] = 0;
if( write( fd, buffer, strlen( buf ) ) < 0 )
perror("writing on stream socket");
}

Take Note of the "+ 1"'s in both of the above examples.

HTH

Rob.
--
http://www.victim-prime.dsl.pipex.com/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #5
In article <50**************************@posting.google.com >,
go****@jeffish.org says...
The following code works just fine.

void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
}

But, obviously, it is not sending the desired string.
The 'message has a \0 at the end. I believe that's why it goes through.
The following code does not work.

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
strcpy(buf, buffer);
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

Here nothing is known about the 'buffer'.
Since you use strcpy and stlen, the message in 'buffer' should be
terminated by \0. Is it?
Maybe the first char in 'buffer' is a \0?

Robb

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #6
go****@jeffish.org (Jeff Crouse) wrote in
news:50**************************@posting.google.c om:

[snip]

The following code does not work.

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
strcpy(buf, buffer);
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

Any suggestions...



You bet it doesnt work. Try this (assuming "buffer" is NULL terminated")
void Macsock::writeData(char *buffer, int fd)
{
// compute # of bytes buffer data really uses

const int nbufbytes = strlen(buffer) * sizeof(buffer[0]) ;
// write buffer to socket

if ( write ( fd, buffer, nbufbytes ) != nbufbytes ) {

perror("writing on stream socket");

}
}


Good day to you.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #7
Charles Burns wrote:

void Macsock::writeData(char *buffer, int fd)
{
// compute # of bytes buffer data really uses

const int nbufbytes = strlen(buffer) * sizeof(buffer[0]) ;


sizeof(buffer[0]) == sizeof(char) == 1, so why bother? You also forgot
to add 1 for the null character.

-Kevin
--
My email address is valid, but changes periodically.
To contact me please use the address from a recent posting.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #8
Rob Williscroft wrote in news:Xns93EE8280A82A2ukcoREMOVEfreenetrtw@
195.129.110.130:

Strange the things you miss, see one error ignore the rest.
I really need a newsreader with a compile before send feature.

strlen() counts the nuber of char before it finds a '\0'. So
if buffer doesn't have one the above will not do what you want.
void Macsock::writeData(char *buffer, size_t size, int fd)
{
char buf[ size + 1 ];
strncpy( buf, buffer, size );
buf[ size ] = 0;
if( write( fd, buffer, strlen( buf ) ) < 0 )
perror("writing on stream socket");
}


void Macsock::writeData(char *buffer, size_t size, int fd)
{
std::string buf( buffer, size );
if( write( fd, buf.c_str(), buf.size() ) < 0 )
perror("writing on stream socket");
}
Rob.
--
http://www.victim-prime.dsl.pipex.com/

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #9
Many thanks to all of you who have helped me. It was a great success.

Now, just to respond to a couple of things for my own sake...

-I apologize for cross-posting the message where I shouldn't have. It
won't happen again.
-This was not my own code, but code that I inherited from a mysterious
previous developer.
-The +1's saved the day, and I feel ready to take on the world with my
new inderstanding of sizeof()
-I realize that sockets are not on-topic in this forum, and I was
originally going to post it in a C group, but i thought class
structure might be part of the problem, so I put it here. What should
I have done?

Again, I am very grateful for your help.

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #10
"Jeff Crouse" <go****@jeffish.org> wrote in message
news:50**************************@posting.google.c om...
In my project, I have successfully opened a sock_stream style socket
connection between two processes and am trying to send 'buffer' to a
connected client, 'fd'.

The following code works just fine.

void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
}

But, obviously, it is not sending the desired string.

The following code does not work.

void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
strcpy(buf, buffer);
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
}

[snip]

Leaving aside the actual code let's look at the interface:

void Macsock::writeData(char *buffer, int fd)

My question is: how does you know the length of the buffer?

If "buffer" is a C style string, that is, it ends with a NUL character then
you can write data directly from buffer, as long as you remember to write
the NUL character too:-

void Macsock::writeData(char *buffer, int fd)
{
if ( write(fd, buffer, strlen(buffer) + 1)) < 0 )
...
}

Note the +1 - this ensures the final NUL is written.

In the case where buffer is not NUL terminated you'll need another parameter
to writeData to supply the length of 'buffer'.
You'll then need to dynamically allocate memory to copy 'buffer' into and
add a NUL.
Alternatively you can write 'length' bytes from buffer and then write a
single NUL character.

void Macsock::writeData(char *buffer, int length, int fd)
{
static const char nul = '\0';
if ( ( write( fd, buffer, length ) < 0 ) ||
( write( fd, &nul, 1 ) < 0 ) )
...
}

HTH,
Roger Orr
--
MVP in C++ at www.brainbench.com


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #11
Francis Glassborow <fr*****@robinton.demon.co.uk> wrote in message
news:<pv**************@robinton.demon.co.uk>...
In article <50**************************@posting.google.com >, Jeff
Crouse <go****@jeffish.org> writes
In my project, I have successfully opened a sock_stream style socket
connection between two processes and am trying to send 'buffer' to a
connected client, 'fd'. The following code works just fine. void Macsock::writeData(char *buffer, int fd)
{
char message[] = "This is a message from the front.";
if(write(fd, message, sizeof(message)) < 0 )
perror("writing on stream socket");
} But, obviously, it is not sending the desired string. The following code does not work. void Macsock::writeData(char *buffer, int fd)
{
char buf[strlen(buffer)];
The number of elements (chars in this case) must be known at compile
time as C++ and C are both statically typed languages.
That's true for C++ (the subject here), but not for C99, where this
definition is perfectly legal.

In C++, of course, we would write something like:

std::vector< char > buf( buffer, buffer + strlen( buffer ) + 1 ) ;
strcpy(buf, buffer);
Declared as above, there is no need for the strcpy.
buf[sizeof(buf)] = '\0';
if(write(fd, buf, sizeof(buf)) < 0 )
perror("writing on stream socket");
} I'm sure that this very simple code is horrifying to any C
programmer, but I am not a C programmer, I'm just a hack trying to
get something finished. All of the stcpy stuff was done because the
connected client I mentioned is very picky about messages being
terminated by a null character.

Actually a C programmer would take one look, note the :: and ignore
the rest because it isn't C. A C++ programmer sees everything else and
immediately wonders why a member function of Macsock is being defined
with an attempt at writing pure C.
There could be various reasons why the interface might use char const*.
Why char*, I don't know; even in C, I would write char const*.
Internally, if I really did need the copy, I would obviously use
std::vector, and not char[]. In this case, however, I wonder why the
copy is even necessary. The simple expression:

if ( write( fd, buffer, strlen( buffer ) + 1 ) < 0 ) {
// ...
}

should do the trick.

However,
Are you responsible for the Macsock class? If so you need to find help
from someone who understands the fundamentals of class design. If not
you need to throw it away and find a good implementation. Frankly the
above code is so far from reasonable C++ in both design and
implementation that the writer of it needs to first learn about the
available tools provided by C++ (std::string, std::fstream etc.)
before attempting a redesign and fresh implementation. Alternatively
you need to find a good third party implementation of a socket class
that meets your needs.


This is really the critical advice. If you don't know a language, it is
hopeless trying to maintain code in it.

--
James Kanze GABI Software mailto:ka***@gabi-soft.fr
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16

[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]
Jul 19 '05 #12

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: Thomas Hervé | last post by:
My problem is not really python specific but as I do my implementation in python I hope someone here can help me. I have two programs that talk through a socket. Here is the code : <server>...
4
by: flupke | last post by:
Hi, I have a gui (made in wxPython) that enables a user to connect to a server and issue some commands. The problem occurs when i try to disconnect the client. It exits but it doesn't return to...
3
by: Daniel | last post by:
TcpClient close() method socket leak when i use TcpClient to open a connection, send data and close the TcpClient with myTcpClientInstance.Close(); it takes 60 seconds for the actual socket on...
4
by: Chris Tanger | last post by:
Context: C# System.Net.Sockets Socket created with constructor prarmeters Internetwork, Stream and TCP everything else is left at the default parameters and options except linger may be changed...
1
by: Dr. J | last post by:
I have an application that opens a socket and connects to another application listening over a port. The problem I am encountering is that when the listening application is closed my application...
2
by: Nuno Magalhaes | last post by:
I've got a simple problem I guess. How do I know when a connection is terminated without losing any data? I do something like the code below, but sometimes between socket.Receive and socket.Send...
1
by: Mr. Beck | last post by:
Hello, Please Help..... I have been working with some tcp/ip socket communication within a C# program recently. Basicly, I have a program (myProblemProgram) that has a socket connected to...
11
by: atlaste | last post by:
Hi, In an attempt to create a full-blown webcrawler I've found myself writing a wrapper around the Socket class in an attempt to make it completely async, supporting timeouts and some scheduling...
3
by: A. W. Dunstan | last post by:
I'm creating a socket as follows: m_networkSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); m_networkSocket.LingerState = new LingerOption(true, 1);...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.