Как отправить () изображение, сохранив его в символьной строке в ANSI C?Проблема с кастингом - PullRequest
0 голосов
/ 19 июня 2011

Я пишу свой собственный сервер в ANSI C (в Linux), и у меня есть одна проблема с отправкой изображений в веб-браузер.Я использую функцию "send ()", чтобы отправить его, и для этого требуется символ *.Итак, я читал файл char по char (используя fgetc), я использовал fread и fgets, но у всех была проблема с приведением содержимого (в большинстве случаев int) к bufor - некоторые байты все еще отсутствовали (например, вместо этого был отправлен 20082020).Я думаю, что есть некоторая проблема с преобразованием, но я использовал sprintf и wchar_t, и он все еще не работает.

У меня есть функция:

void send_www(char *buff, int cd){      
if(send (cd, buff, strlen(buff), 0) < 0) {
        perror ("send()");
        exit (1);

, которую я здесь использую:

//  while (fread(znak, sizeof(char), i,  handler) != 0) {
    for (j = 0; j < i; j++) {
    a = fgetc(handler);
    sprintf(znak, "%ls", a);
    send_www(znak, cd);
    }

, где i - длина файла изображения, znak - символ* (в этой версии wchar_t *).Вы также можете увидеть мою предыдущую попытку использовать fread.

Ответы [ 3 ]

3 голосов
/ 19 июня 2011

Трудно сказать без подробностей - вы можете опубликовать какой-нибудь код?

Прежде всего, убедитесь, что вы открываете файл изображения с помощью двоичной опции , например, fopen (имя файла,"rb");

Если вы просто читаете двоичный файл и отправляете его в сокет, где другой конец ожидает двоичный файл, вам не нужно никакого приведения или sprintf.

Похоже, выпутать тип char со строками.Строка AC - это последовательность символов, оканчивающаяся нулями.Ваш файл изображения представляет собой двоичный файл, содержащий последовательность символов, но это не строка.Функция send () принимает указатель на последовательность байтов, а не на строки.Чтобы проиллюстрировать это, посмотрите на эту последовательность символов (или байтов):

255, 255, 255, 0, 0, 0, 255, 255, 255

В некоторых форматах файлов изображений это может быть три пикселя RGB, поэтому белый, черный белый.9 байт.Может храниться в буфере символов [9].Если вы вызовете strlen () для этого, вы получите результат 3. strlen () считается до тех пор, пока не увидит нулевой символ.Если вы читаете эти байты из файла без двоичного флага, он может трансформироваться, и вы можете получить меньше или больше байтов, чем на самом деле в файле (в зависимости от содержимого, ОС и т. Д.).

Грубые поясненияследующий код:

char buffer[1024];
FILE *infile = fopen("test.gif", "rb"); // open a file (check for failure in real code)
int nread = fread(buffer, 1, 1024, infile);
// assume socket is connected (check for number of bytes sent or error in real code)
send(socket, buffer, nread, 0); 
fclose(infile); // close the file

Чтобы прочитать двоичный файл и отправить данные в сокет, вам нужно выполнить что-то вроде приведенного выше фрагмента.Вы, вероятно, продолжите чтение, пока не дойдете до конца файла, фрагмент читается только один раз.Также в реальном коде вы должны проверить, сколько байтов было фактически отправлено (в возвращаемом значении от send) и продолжать вызывать send, пока вы не отправите все данные или не произойдет ошибка.

2 голосов
/ 19 июня 2011

Вы используете strlen(). strlen() останавливается и возвращает размер после достижения байта \0. Изображения и двоичные данные могут иметь нулевое байтовое значение в любом месте, поэтому strlen() в таких случаях бесполезно.

Вам нужно изменить свою функцию на:

send_www(unsigned char *buff, size_t buf_len int cd);

И передайте ему размер изображения, чтобы вы могли безопасно send() иметь соответствующий размер.

В вашем случае кажется, что вы уверены, что это строка wchar_t, используйте соответствующую функцию, wcslen(), а не strlen():)

1 голос
/ 19 июня 2011

Я предполагаю, что проблема в том, что данные вашего изображения содержат символы (\0), поэтому они не отправляются, потому что вы используете strlen(), чтобы выяснить, сколько данных отправлять.

...