Программирование сокетов в c - PullRequest
1 голос
/ 06 сентября 2010

Я создал небольшие программы сокетов (клиент / сервер).Клиент будет передавать все форматы файлов на сервер. Проблема, с которой я сейчас сталкиваюсь - я читаю mp3-файл в двоичном режиме и отправляю на сервер.Сервер читает содержимое из буфера и создает файл. Но когда я пытаюсь открыть файл, он не открывается.Но размер остается таким же, как оригинальный.Может кто-нибудь указать, где я делаю неправильно.Вот мой код на стороне сервера:

    recv(newSocket,fileSize,50,0); //Receiving file size

//  buffer=malloc(atoi(fileSize));
    int i=0;

    recv(newSocket,buffer,atoi(fileSize),0);
    fwrite(buffer,1,atoi(fileSize),out);

На стороне клиента: fread (данные, 1, размер, файл);

    sprintf(temp,"%ld",lSize);

    send(socketDes,temp,strlen(temp),0);


    send(socketDes,data,strlen(data),0);

Ответы [ 2 ]

4 голосов
/ 06 сентября 2010

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

Если вы используете TCP (потоковое соединение), когда вы идете читать из сокета в буфер (вы, вероятно, используете массив byte / char), вы получите только все байты, которые доступны в время звонка. Вызов функции чтения вернется немедленно, но буфер, в который записываются данные, будет заполнен только частично.

Чтобы это исправить, вам нужно проверить, сколько байтов было на самом деле прочитано из сокета (обычно вызов чтения вернет это число), а затем повторно считывать из сокета, пока у вас не будет всех байты вам нужны.

Обновление

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

Вы также можете решить эту проблему на стороне отправителя. Даже если между вызовами на send есть команда режима сна, send будет отправлять только определенное количество данных за вызов. Вам нужно будет поместить send в цикл и продолжать отправлять данные, пока вы не отправите все данные, которые хотите отправить.

Рассмотрим следующий (непроверенный) псевдо-код для recv:

int numberOfReceivedBytes=0;
while (numberOfReceivedBytes<fileSize){
    numberOfReceivedBytes+=recv(newSocket,buffer + numberOfReceivedBytes,sizeof(*buffer),0)
}

Кроме того, похоже, что когда вы читаете размер файла из сокета, вы можете случайно получить часть самого файла в дополнение к размеру файла. Убедитесь, что вы точно знаете, сколько байтов будет указывать на фактический размер файла, и читайте только столько байтов. Кроме того, atoi работает только для строкового (ASCII) представления числа. Ваш сервер получает фактический номер.

Для отправки:

int numberOfSentBytes=0;
while (numberOfSentBytes<fileSize){
    numberOfSentBytes+=send(newSocket,buffer+numberOfSentBytes,fileSize-numberOfSentBytes+1,0);
}
0 голосов
/ 06 сентября 2010

Пытаетесь открыть файл как, с помощью MP3-плеера после его передачи?

Возможно, вы не пишете выходной файл в «двоичном» режиме; в некоторых операционных системах это приведет к переводу байтов, что приведет к разрушению файла, если он действительно двоичный, а не текстовый.

Если вы открываете файл для записи, используя fopen(), включите "b" во второй аргумент:

FILE *out = fopen("incoming.mp3", "wb");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...