Question

I am using a tcp server that I wrote for handling inputs into a database. I have a tcp client sitting on a server that sends the filename to a tcp server sitting on a different linux server. once the filename is received the linux server goes into a shared folder and pulls the file then inserts it into the database.

my problem is with correctly declaring the buffer and clearing it to make sure I get the correct filename without any gibberish added or anything removed from it.

right now it is working like this:

 char data[1024];

which is fine but it does not automatically delete the buffer completely, so i tried to implicitly allocate memory to "data" such as:

char *data = (char*) malloc(1024 * sizeof(char));
...
free(data);

OR

char *data = new char[1024]; 
...
delete[] data;

For some reason the above two declaration are declaring a buffer of size =8 I got this using

sizeof(data);

also what I am receiving is only 8 characters long. I am not sure why it is doing this, any help??

EDIT

char *data = (char*)malloc(1048 * sizeof(char));
if(data==NULL) exit(1);
cout << "DATA Size: " << sizeof(data) << "\n";
int msglen = read(conn, data, sizeof(data));
cout << "Server got " << msglen << " byte message: " << data << "\n";

if(write(conn, &msglen, sizeof(msglen))<0){
    cout << "Failed to write back to the client " << strerror(errno);
}

free(data);
close(conn);
Était-ce utile?

La solution

There are several things wrong with your code. 1) dont use malloc - you flagged your question as c++ - use malloc only when necessary replace it with:

const int dataSize = 1024;
char *data = new char[dataSize];

2) sizeof(data) when data is char* returns 8 because it returns size of a pointer not an array when you declare data as array sizeof will return bytes occupied by whole array. you should replace you read with:

int msglen = read(conn,data,dataSize)

3) I assume that u want to write data u've just received back to sender.. Then:
in write function you put sizeof(msglen) as third argument which will (mostly) always return 4. remove sizeof( ).

write(conn, data, msglen);

after you are done with the data dont forget to clear the memory using:

delete[] data;

use delete[] always when you assigned memory with new[].

Autres conseils

API write(int socket, char *buf, int len);

Code becomes this:

write(con, data, msglen);

Assuming you can't use the stack (e.g. char buf[1024]), using naked pointers is discouraged as bad style and bug prone. Instead, use RAII and some variant of amanged memory, such as shared_ptr or unique_ptr.

#include <memory> and use a std::shared_ptr<>, or std::unique_ptr<> plus std::move() to return the buffer:

std::size_t bufSize = 1024;
std::unique_ptr<char[]> myUniqueBuf(new char[bufSize]);
ssize_t msglen = ::read(conn, *myUniqueBuf, bufSize); // return type is ssize_t, not int
return std::move(myUniqueBuf); // If you need to return the buffer

// I think you will probably prefer a shared_ptr<> because it has a copy
// constructor which makes it easier to pass around and return from functions
std::shared_ptr<char[]> mySharedBuf(new char[1024]);
ssize_t msglen = ::read(conn, *mySharedBuf, bufSize); // return type is ssize_t, not int
ssize_t bytesOut = ::write(conn, *mySharedBuf, msglen);
return mySharedBuf;

The advantage to std::shared_ptr or std::unique_ptr is that you don't have to worry about cleaning up a naked pointer (i.e. calling delete[] data;) because with managed memory it will happen automatically for you when the buffer handle goes out of scope or the reference count goes to zero (e.g. myUniqueBuf or mySharedBuf).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top