PureBasic - форум

Информация о пользователе

Привет, Гость! Войдите или зарегистрируйтесь.


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Проблемы с передачей файлов (Network)


Проблемы с передачей файлов (Network)

Сообщений 1 страница 7 из 7

1

Здравствуйте,  не могу нормаьно передать файл по сети, передается только определенная часть, или фрагмент файла, например музыка вместо 7 минут, идет 7 секунд (отрывок) Что я не так делаю?

На клиенте такой код:
Открываю фал, получаю его размер, отправляю размер файла обычной строкой, а потом и сам файл через буфер.

Код:
If ReadFile(0, "1.mp3")
length = Lof(0)
*MemoryID = AllocateMemory(length)
If *MemoryID
ReadData(0, *MemoryID, length)
SendNetworkString(Server, ""+length)
ReAllocateMemory(*Buffer, length)
SendNetworkData(Server, *MemoryID, length)
EndIf
EndIf

Сервер:
Переменная co просто переключает прием данных, после того как пришла строка с размером файла.

Код:
Case #PB_NetworkEvent_Data
ReceiveNetworkData(Client, *Buffer, 1000)

If co = 0
len$ = PeekS(*Buffer)
length = ValF(len$)
co = 1
FillMemory(*Buffer, 500)
Else
*MemoryID = AllocateMemory(length)
ReceiveNetworkData(Client, *MemoryID, length)
CreateFile(111, "2.mp3")
WriteData(111, *MemoryID, length)
CloseFile(111)
Debug "Файл создан"
co = 1
EndIf

В конце почему то я вижу 5-6 сообщений в дебаге "Файл создан", почему так, поправьте или обьясните что не так пожалуйста.

0

2

Такой код нормально работать не будет.
Во первых, то что данные были переданы двумя вызовами функций SendNetworkxxxx не значит что они будут приняты так же двумя вызовами функции ReceiveNetworkData. Нужно четко определить длину сообщения с размером файла и лучше что бы это было число, а не строка. Тогда первых 8 байт достаточно для информации о размере файла.
Как писал выше, не факт что все данные файла будут приняты за один вызов функции ReceiveNetworkData. Так что создавать файл нужно при получении размера файла, а закрывать когда указанное число байт было получено (или потеряна связи с клиентом), а во все остальные вызовы ReceiveNetworkData, нужно дописывать данные в файл.

И еще учти что Москва сеть не резиновая и нужно проверять что возвращает SendNetworkxxxx. Если -1, то сетевой буфер перегружен и следует подождать некоторое время и повторно отправить те же данные.

Так же посмотри это. http://www.cyberforum.ru/programming-th … ost5041232

0

3

Пётр написал(а):

Во первых, то что данные были переданы двумя вызовами функций SendNetworkxxxx не значит что они будут приняты так же двумя вызовами функции ReceiveNetworkData.

Проверял много раз, принимают нормально. А можно какой-то пример нормальный, или подправьте мой код пожалуйста.

Вот жалко что в новых версиях убрали функции ReceiveNetworkFile() и SendNetworkFile(), мне нужно просто передать изображение размером не более 50 кб. А загружать на фтп, и потом скачивать как то не очень удобно, и быстро. Есть ли какая нибудь альтернатива?

Отредактировано Racer (29.12.2013 00:59:32)

0

4

Пардон, нашел на оф форуме эти процедуры, всё работает.

0

5

Извиняюсь, можно ли как то из этого кода убрать проверку, что бы данные сразу принимались без проверки заголовка FILE, сижу экспериментирую, понять не могу...

Клиент:

Код:
Procedure.i NetworkSendFile(Connection.i, Filename$)
Protected Result.i, File.i, Size.q, *Buffer, Offset.i
File = ReadFile(#PB_Any, Filename$)
If File
Size = Lof(File)
Filename$ = "FILE:" + GetFilePart(Filename$) + ":" + Str(Size)
*Buffer =  AllocateMemory(Size + Len(Filename$) + 1)
If *Buffer
PokeS(*Buffer, Filename$)
If ReadData(File, *Buffer + Len(Filename$) + 1, Size) = Size
If SendNetworkData(Connection, *Buffer, MemorySize(*Buffer)) = MemorySize(*Buffer)
Result = #True
EndIf
EndIf
EndIf
CloseFile(File)
EndIf
ProcedureReturn Result
EndProcedure


InitNetwork()
Connection = OpenNetworkConnection("46.175.161.147", 22006)
If Connection
If NetworkSendFile(Connection, "1.mp3")
MessageRequester("Сообщение", "Файл передан")
Else
MessageRequester("Сообщение", "Ошибка передачи файла")
EndIf
CloseNetworkConnection(Connection)
EndIf

Сервер

Код:
Procedure.i NetworkReceiveFile(ClientID.i, *Buffer, RcvBytes.q)
Protected Line$, Filename$, FileSize.q, *NewBuffer, Count.i
Line$ = PeekS(*Buffer, RcvBytes)
If StringField(Line$, 1, ":") = "FILE"
Filename$ = StringField(Line$, 2, ":")
FileSize = Val(StringField(Line$, 3, ":"))
If FileSize > 0
RcvBytes - Len(Line$) - 1
File = CreateFile(#PB_Any, "2.mp3")
If File
WriteData(File, *Buffer + Len(Line$) + 1, RcvBytes)
EndIf
Count = 0      
While RcvBytes < FileSize And Count >= 0
Count = ReceiveNetworkData(ClientID, *Buffer, MemorySize(*Buffer))
If Count > 0
If IsFile(File)
WriteData(File, *Buffer, Count)
EndIf
RcvBytes + Count
EndIf
Wend
If IsFile(File)
If RcvBytes = FileSize
Result = #True
EndIf
CloseFile(File)
EndIf
EndIf
EndIf
ProcedureReturn Result
EndProcedure


InitNetwork()
Server = CreateNetworkServer(#PB_Any, 22006)
If Server
Repeat
SEvent = NetworkServerEvent()
If SEvent
ClientID = EventClient()
If SEvent = #PB_NetworkEvent_Data
*Buffer = AllocateMemory(1024)
If *Buffer
RcvBytes = ReceiveNetworkData(ClientID, *Buffer, 1024)
If RcvBytes > 0
Line$ = PeekS(*Buffer, 5)
If Left(Line$, 5) = "FILE:"              
If NetworkReceiveFile(ClientID, *Buffer, RcvBytes)
MessageRequester("Сообщение", "Файл принят")
Else
MessageRequester("Сообщение", "Ошибка приема файла")
EndIf
Else
; do the other receive stuff
MessageRequester("Сообщение", "Приняты данные, но это не файл")


EndIf
EndIf
FreeMemory(*Buffer)
EndIf
EndIf
Else
Delay(100)
EndIf
ForEver
EndIf

0

6

В клиенте убрать "FILE:" +.

Код:
Filename$ = GetFilePart(Filename$) + ":" + Str(Size)

В сервере убрать строку.

Код:
If StringField(Line$, 1, ":") = "FILE"

Следующие за ней строки должны быть такими.

Код:
Filename$ = StringField(Line$, 1, ":")
FileSize = Val(StringField(Line$, 2, ":"))

0

7

Спасибо!

0


Вы здесь » PureBasic - форум » Вопросы по PureBasic » Проблемы с передачей файлов (Network)