LINUX.ORG.RU

Как передать unsigned char* без потерь в сокете?

 


1

3

Передаю изображение с сервера на клиент, но черный экран. Клиент

        FILE* f = fopen("Screen.tga", "wb");
        if (!f) {
        }
        unsigned char tgaHeader[12] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
        unsigned char header[6];
        n = read(sockfd, (char*)tgaHeader, sizeof(tgaHeader));
        fwrite((unsigned char*)tgaHeader, sizeof(tgaHeader), 1, f); 
        n = read(sockfd, (char*)header, sizeof(header));
        fwrite((unsigned char*)header, sizeof(header), 1, f);
        // Записываем данные изображения:
        bzero(buffer, buflen);
        n = read(sockfd, buffer, buflen);
        unsigned long j = (unsigned long)atol(buffer);
        std::cout << buffer << std::endl;
        std::cout<<'\n' << "j=" << j << std::endl;
        bzero(buffer, buflen);
        n = read(sockfd, buffer, j);
        fwrite((unsigned char*)buffer,j, 1, f);
        bzero(buffer, buflen);
        fclose(f);
сервер
    FILE*sFile =fopen("Screen.tga", "wb");
    if (!sFile) {
    }
    header[0] = ScreenWidth % 256;
    header[1] = ScreenWidth / 256;
    header[2] = ScreenHeight % 256;
    header[3] = ScreenHeight / 256;
    header[4] = BMI.bmiHeader.biBitCount;
    header[5] = 0;
    fwrite(tgaHeader, sizeof(tgaHeader), 1, sFile);
    n = write(newsockfd[current], (char*)tgaHeader, sizeof(tgaHeader));
    fwrite(header, sizeof(header), 1, sFile);
    n = write(newsockfd[current], (char*)header, sizeof(header));
    fwrite(ImageBuffer, BMI.bmiHeader.biSizeImage, 1, sFile);
    char* s = new char[100];
    ultoa(BMI.bmiHeader.biSizeImage, s,100);
    for (int i = 0; i < 100; i++)
        ((type*)args)[current].lalk->buffer[i] = s[i];
    n = write(newsockfd[current], ((type*)args)[current].lalk->buffer, buflen);
    n = write(newsockfd[current], (char*)ImageBuffer, BMI.bmiHeader.biSizeImage);
    fclose(sFile);

Непонятно, у вас и сервер и клиент пишет в файл! А читать из файла кто будет? Разве сервер не должен прочитать изображение из файла?

sigurd ★★★★★
()
Последнее исправление: sigurd (всего исправлений: 1)
Ответ на: комментарий от sigurd

Там есть чтение точнее скриншот делается этот код я не постил, просто кода много, меня волнует преобразование из unsigned char* в char* и обратно для сокета

bad_master
() автор топика
Последнее исправление: bad_master (всего исправлений: 1)
Ответ на: комментарий от bad_master

4.2

The Microsoft-implemented POSIX function name write is a deprecated alias for the _write function.

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/posix-write?view=vs-2019

int _write(
   int fd,
   const void *buffer,
   unsigned int count
);

https://docs.microsoft.com/en-us/cpp/c-runtime-library/reference/write?view=vs-2019

fsb4000 ★★★★★
()
Ответ на: комментарий от fsb4000

Забавно мне теперь нужно перелопатить новый сокет, потому что виндузятский выдает ошибку рантайма, а как же другие разрабы передают картинки и вообще любые файлы по сети?

bad_master
() автор топика
Последнее исправление: bad_master (всего исправлений: 1)

А зачем читать файл? Почему б тебе тупо не отобразить свой файл Screen.tga в память (функция mmap() в нормальных позикс-совместимых ОСях и CreateFileMapping, MapViewOfFile в виндах)? Размер файла в линуксах через stat узнавать можно, в виндах функцией GetFileSize, только под винду надо открывать файл винапишными функцями, типа https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-createf...

SZT ★★★★★
()

И вообще, что у тебя за фигня в сервере написана? Вот ты зачем-то открываешь файл Screen.tga на запись

    FILE*sFile =fopen("Screen.tga", "wb");
Зачем ты его на запись открываешь? Ты ж его вроде передавать собрался.

Опция w для fopen() вот что значит

w Truncate file to zero length or create text file for writing. The stream is positioned at the beginning of the file.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от bad_master

Забавно мне теперь нужно перелопатить новый сокет, потому что виндузятский выдает ошибку рантайма

Тебе надо почитать про winsocks, https://docs.microsoft.com/en-us/windows/win32/winsock/finished-server-and-cl...

Там всякие специальные виндоспецифичные функции типа WSAStartup, WSACleanup надо вызывать, и функции write и read там не работают, надо send, recv юзать.

SZT ★★★★★
()
Ответ на: комментарий от SZT

Винду поддержать через WSL :-) а POSIX - это стандарт для систем, вытесненных Linux-ом

Begemoth ★★★★★
()

Почему бы не заюзать библиотеки?

paramon
()
Ответ на: комментарий от Begemoth

Зависит от задачи. Если просто данные без потерь гонять, то grpc перебор. А если rpc то да.

А то primitiven obsession )

invy ★★★★★
()
Ответ на: комментарий от invy

Avro, protobuf

Велосипеды - это стрельба в ногу.

Это скорее всего учебная задача, в которой сказано, что надо именно tga файл через обычный сокет передать, и решение с Avro, protobuf вряд ли одобрят.

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от invy

Я просто к тому, что protobuf - это только формат сериализации, но не средство межпрограммного взаимодействия.

Begemoth ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.