2013-09-16 2 views
0

Я использую сервер tcp, который я написал для обработки входов в базу данных. У меня есть клиент tcp, сидящий на сервере, который отправляет имя файла на сервер tcp, сидящий на другом Linux-сервере. после получения имени файла сервер linux переходит в общую папку и вытаскивает файл, а затем вставляет его в базу данных.правильно объявляющий буфер для сервера tcp C++

Моя проблема заключается в правильном объявлении буфера и очистке его, чтобы убедиться, что я получаю правильное имя файла без добавления таблеток или чего-либо, что удалено из него.

прямо сейчас он работает так:

char data[1024]; 

это хорошо, но это не будет автоматически удалять буфер полностью, поэтому я попытался неявно выделить память для «данных», такие как:

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

ИЛИ

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

по какой-то причине двух вышеупомянутых декларации объявляют буфер от размера = 8 Я получил это с помощью

sizeof(data); 

также то, что я получаю, всего 8 символов. Я не уверен, почему он это делает, любая помощь?

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); 
+2

Как вы принимаете данные? Причина sizeof (data) возвращает 8, потому что данные являются указателями, а в 64-битной системе размер указателя будет 8 байтов. –

+0

см. В разделе edit, чтобы ответить на ваш вопрос. – laitha0

+0

данные о символах [1024]; память, занятая этим, автоматически будет освобождена после выхода из области видимости. –

ответ

1

Есть несколько вещей неправильно с вашим кодом. 1) не использовать таНос - вы помечен свой вопрос, как C++ - использование таНос только при необходимости заменить его:

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

2) SizeOf (данные), когда данные символьные * возвращает 8, поскольку она возвращает размер указателя а не массив, когда вы объявляете данные, поскольку массив sizeof будет возвращать байты, занятые целым массивом. вы должны заменить прочитать с:

int msglen = read(conn,data,dataSize) 

3) Я предполагаю, что у хочу записать данные u've только что получил обратно отправителю .. Тогда:
в функции записи вы положили SizeOf (msglen) в качестве третьего аргумента который будет (главным образом) всегда возвращать 4. remove sizeof().

write(conn, data, msglen); 

после того, как вы закончите с данными не забудьте очистить память с помощью:

delete[] data; 

использовать delete[] всегда, когда вы назначили память с new[].

+1

Не забудьте «удалить [] данные», а не «удалить данные», так как выделение, используемое массивом, было выполнено с помощью 'new []'. – Sean

1

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

код становится это:

write(con, data, msglen); 
0

Предполагая, что вы не можете использовать стек (например char buf[1024]), используя голые указатели не рекомендуется, как плохой стиль и ошибка склонной. Вместо этого используйте RAII и некоторый вариант измененной памяти, такой как shared_ptr или unique_ptr.

#include <memory> и использовать std::shared_ptr<> или std::unique_ptr<> плюс std::move() вернуть буфер:

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; 

Преимущество std::shared_ptr или std::unique_ptr является то, что вам не придется беспокоиться об очистке голого указателя (т.е. вызова delete[] data;), потому что с управляемой памятью это произойдет автоматически для вас, когда дескриптор буфера выходит из области видимости или счетчик ссылок идет на ноль (например, myUniqueBuf или mySharedBuf).

Смежные вопросы