Народ, пожалуйста, приведите листинг кода, реализирующего пример того, как передать от клиента серверу файл, через ВинСок.
p.s. открываю файл в бинарном режиме, загружаю его всего в переменную и далее:
а) когда кладёшь эту переменную в новый файл, получается копия файла.
б) когда пытаюсь передать эту переменную через ВинСок серверу и уже через него создаю файл - ничерта не получается. Понятно, что ошибок до фига, но каких?
If ws.State = sckConnected Then
Dim x As Integer
Dim vBuf As String * 1000
Open "C:\1.exe" For Binary As #1
x = LOF(1)
MsgBox x
Do Until EOF(1)
Get #1, , vBuf
ws.SendData vBuf
Pause_2sek
MsgBox vBuf, , "Отправил"
Loop
Close #1
Сервак:
Private Sub ws_DataArrival(ByVal bytesTotal As Long)
Dim vData As String
Dim x As Integer
x = 0
ws.GetData vData
Open "C:\2.exe" For Binary As #1
x = LOF(1)
If x = 0 Then x = 1
Seek #1, x
Put #1, , vData
MsgBox vData, , "Принял"
Close #1
End Sub
Не знаю пробывал по-разному не получается... может кто подскажет код?
Ну, есть и что? Больше половины кодов на vbstreets, vbrussian и даже на буржуйских сайтах битые. Есть и рабочие, но я не могу понять принцип их работы. Вот я и спрашиваю как написать этот код в откровенно дебильно лёгкой форме. Признаюсь для себя... ибо новичок и нихрена не понимаю.
Да, кстати, а как и когда применяется DoEvents?
Больше всего нелюблю когда некий новичек, который называет даже себя так, говорит что коды битые...
Примеров и статей по винсоку достаточно. Если я приведу готовый исходный код, он будет работать, но чтобы ты в нём разобрался "до последней косточки" мне придется написать тут целую статью и прокоментировать каждую строчку исходного кода. Не поленись пойщи примеры сам. Тебе подойдут примеры практически всего: прокси серверов, сетевых пейджеров, сетевых игр итп итд... если это в виде статье, всё будет достаточно хорошо прокомментировано.
DoEvents применяется при длительных операций, когда нужно помимо этой затянувшийся операции, ещё отработать другие события. Например при бесконечном цикле, форма "умрет", её нельзя будет потягать, ресайзить, в скоре такое приложение получит статус зависшего, к заголовку окна добавится "Не отвечает)", а после определенного времени такое приложение вовсе будет убито операционной системой. Если в этот бесконечный цикл вставить DoEvents (в любое место), то при выполнении этой команды, управление передастся событиям которые находятся в очереди, т.е. тот же ресайз, перемещение или перерисовка... в итоге приложение отвечает на сообщения, т.е. не считается зависшей... В эти события могут входить и свои личные, т.е. например событие которое будет "общаться с публикой" (например показывать прогресс % работы длительной операции)....
Код приводить не буду. Вот примерные правила отправки.
Лучше сначала отправить такой типа код FF на том конце ага пришла команда, счас пойдут данные файла (открываешь файл и тд и тп).
В начале отправляемого сообщения прилепи какой-нибудь код определенного размера, например 2 символа. И в конце тоже определенный код. Например DDДанные файлаEE, получая сообщение отрезаешь 2 символа спереди, анализируешь, к примеру DD это данные, ага, читаем данные, проверяем в конце EE ага, дошел весь пакет и данные будут еще, в ответ отсылаем например СС, что значит принял, жду следующего пакета, только по приеме СС снова отсылаешь следующую порцию данных , то же анализируешь и тд, по исчерпывании данных отправляешь например QQ, что значит усе данных больше ек.
Некоторые скажут, а нафига стока много букавок, зато надежно, уже сколько пользуюсь и ни чего не глючит. Можно там контрольную сумму отсылать или еще как контролировать, ошибки пересылать и тд и тп.
А ты открывешь бинарник и читаешь в строку, ты смотрел, что у тебя там получается в той строке и затем пишешь строку в бинарник, там может оказаться очень странные данные и пересылать следует только символьные данные, а винарные кодировать в вид /045, те по кодам а при приеме назад переделывать в бинарник и сохранять, короче все очень мудро получается.
В начале отправляемого сообщения прилепи какой-нибудь код определенного размера, например 2 символа. И в конце тоже определенный код. Например DDДанные файлаEE, получая сообщение отрезаешь 2 символа спереди, анализируешь, к примеру DD это данные, ага, читаем данные, проверяем в конце EE ага, дошел весь пакет и данные будут еще, в ответ отсылаем например СС
Неверно. по двум причинам:
1. В самих ДАННЫХ ФАЙЛА может содержаться твои "EE", "CC" и пр.
2. Гораздо лучше и быстрей в начале отослать строку типа "Get file. Length: 406254<<". И потом просто отсылаешь этот файл. Как его длина(406254) будет передана считай что все окей
Ну, вот например вроде как рабочий код... кое как достал.
Как говорят не поленился, хотя реально нихрена не мог найти.
Передача:
Public Sub SendData(sFile As String, sSaveAs As String, tcpCtl As Winsock)
On Error GoTo ErrHandler
Dim sSend As String, sBuf As String
Dim ifreefile As Integer
Dim lRead As Long, lLen As Long, lThisRead As Long, lLastRead As Long
ifreefile = FreeFile
' Open file for binary access:
Open sFile For Binary Access Read As #ifreefile
lLen = LOF(ifreefile)
' Loop through the file, loading it up in chunks of 64k:
Do While lRead < lLen
lThisRead = 65536
If lThisRead + lRead > lLen Then
lThisRead = lLen - lRead
End If
If Not lThisRead = lLastRead Then
sBuf = Space$(lThisRead)
End If
Get #ifreefile, , sBuf
lRead = lRead + lThisRead
[B]sSend = sSend & sBuf[/B]
Loop
lTotal = lLen
Close ifreefile
bSendingFile = True
'// Send the file notification
tcpCtl.SendData "FILE" & sSaveAs
DoEvents
'// Send the file
[B]tcpCtl.SendData sSend[/B]
DoEvents
'// Finished
tcpCtl.SendData "FILEEND"
bSendingFile = False
Exit Sub
ErrHandler:
MsgBox "Err " & Err & " : " & Error
End Sub
Я понять не могу строку sSend = sSend & sBuf - это означает что файл считывается по 64 кб в переменную sSend и РАЗОМ отправляется в сеть???
А строка tcpCtl.SendData sSend означает что Public Sub SendData исполняется только один раз??? Да и почему перед ней указан DoEvents зачем передавать управление событиям "находящимся в очереди", да и собственно каким событиям? Объясните, пожалуйста, принцип действия кода???
Заранее спасибо большое.
Приём:
Private Sub tcpClient_DataArrival(ByVal bytesTotal As Long)
Dim strData As String
Dim ifreefile
DoEvents
tcpClient.GetData strData
If Right$(strData, 7) = "FILEEND" Then
bFileArriving = False
lblProgress = "Saving File to " & App.Path & "\" & sFile
sArriving = sArriving & Left$(strData, Len(strData) - 7)
ifreefile = FreeFile
If Dir(sFile) <> "" Then
MsgBox "File Already Exists"
Else
Open sFile For Binary Access Write As #ifreefile
[B]Put #ifreefile, 1, sArriving[/B]
Close #ifreefile
ShellExecute 0, vbNullString, App.Path & "\" & sFile, vbNullString, vbNullString, vbNormalFocus
End If
lblProgress = "Complete"
ElseIf Left$(strData, 4) = "FILE" Then
bFileArriving = True
sFile = Right$(strData, Len(strData) - 4)
ElseIf bFileArriving Then
lblProgress = "Receiving " & bytesTotal & " bytes for " & sFile & " from " & tcpClient.RemoteHostIP
[B]sArriving = sArriving & strData[/B]
End If
End Sub
А здесь соответственно все куски файла из переменной sSend (ВинСок её поделил, так?) принимаются в sArriving, которая по окончании передачи записывается в sFile???
В начале отправляемого сообщения прилепи какой-нибудь код определенного размера, например 2 символа. И в конце тоже определенный код. Например DDДанные файлаEE, получая сообщение отрезаешь 2 символа спереди, анализируешь, к примеру DD это данные, ага, читаем данные, проверяем в конце EE ага, дошел весь пакет и данные будут еще, в ответ отсылаем например СС
Неверно. по двум причинам:
1. В самих ДАННЫХ ФАЙЛА может содержаться твои "EE", "CC" и пр.
2. Гораздо лучше и быстрей в начале отослать строку типа "Get file. Length: 406254<<". И потом просто отсылаешь этот файл. Как его длина(406254) будет передана считай что все окей
Дак если всегда прилепляешь то и всегда отлепляешь, главное размер этих кодов и все.