TCP Print, нужна ли кодировка отсылаемых данных в Base64 ?

Раздел посвящен программированию с использованием Power Basic.
jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

TCP Print, нужна ли кодировка отсылаемых данных в Base64 ?

Сообщение jangle » 25.01.2007 (Чт) 14:02

Пробовал передавать ZIP архивы по локалке, на другой комп приходят битыми.
Хотя размер совпадает, может все-таки нужна перекодировка в Base64? Однако это увеличит размер передаваемого файла в несколько раз, может есть другие пути методы передачи бинарников по TCP/IP? (кроме FTP)

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 25.01.2007 (Чт) 15:28

Еще один забавный прикол, размер буфера Tcp Recv влияет на корректность загрузки данных, например буфер в 8 кбайт, нормально загрузил с сервера архив в 13 Мбайт, но если увеличить буфер до 16 кбайт, грузится только 11 кбайт! Как это объяснить?


Работает:

Код: Выделить всё
    Do
              Tcp Recv hEcho, 8192, sBuffer                   
                sPacket = sPacket + sBuffer
    Loop Until sBuffer = "" Or IsTrue Eof(hEcho) Or IsTrue Err     



Загружает только 11 кбайт:

Код: Выделить всё
    Do
              Tcp Recv hEcho, 16384, sBuffer                   
                sPacket = sPacket + sBuffer
    Loop Until sBuffer = "" Or IsTrue Eof(hEcho) Or IsTrue Err     

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 25.01.2007 (Чт) 19:18

Вообще протокол TCP предназначен для передачи любых данных :)
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

volo
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 142
Зарегистрирован: 10.12.2004 (Пт) 11:18
Откуда: Soviet Union

Re: TCP Print, нужна ли кодировка отсылаемых данных в Base64

Сообщение volo » 25.01.2007 (Чт) 20:29

jangle писал(а):Пробовал передавать ZIP архивы по локалке, на другой комп приходят битыми.
Хотя размер совпадает, может все-таки нужна перекодировка в Base64? Однако это увеличит размер передаваемого файла в несколько раз, может есть другие пути методы передачи бинарников по TCP/IP? (кроме FTP)


Такой прикол у меня был несколько лет назад. nix сервер не пропускал изображения для загрузки кроме прописанных в нем.

т.е. мой формат изображения приходил такой же о котором ты говоришь "битый". См. настройки своего ПО на сервере.

По началу заменял бинарники на типа JPEG формат, тупо менял расширения, то тогда прокатывало.

Напрмер файл "рогаикопыта.изо" не прокатывал, а "рогаикопыта.jpg" прокатывал нормально.

поковыряйся в своем серверном ПО

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 25.01.2007 (Чт) 21:19

Сколь редкий бред вы говорите...
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

PBDN
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 21.10.2006 (Сб) 22:10

Сообщение PBDN » 26.01.2007 (Пт) 9:07

jangle писал(а):Еще один забавный прикол, размер буфера Tcp Recv влияет на корректность загрузки данных, например буфер в 8 кбайт, нормально загрузил с сервера архив в 13 Мбайт, но если увеличить буфер до 16 кбайт, грузится только 11 кбайт! Как это объяснить?


Обьяснение здесь
http://www.powerbasic.com/support/forum ... 01175.html

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 26.01.2007 (Пт) 10:01

поковыряйся в своем серверном ПО


Ну у меня вообщето клиент и сервер написаны на PB:


Сервер:

Код: Выделить всё
#Compile Exe
#Dim All

#Include "Win32api.inc"
#Include "WS2_32.inc"

Declare Function TcpProc (ByVal hDlg As Dword, ByVal wMsg As Long,ByVal wParam As Long,ByVal lParam As Long)  As Long

Global Prt    As Dword  'Номер порта который открывает сервер
Global TimOut As Dword  'Тайм-аут

%TCP_ACCEPT = %WM_USER + 4093  ' Любая величина больше чем %WM_USER + 500
%TCP_ECHO   = %WM_USER + 4094  ' Любая величина больше чем %WM_USER + 500

'-----------------------------------------------------------------------
'оконная процедура
Function TcpProc (ByVal hDlg As Dword, _
                  ByVal wMsg As Long, _
                  ByVal wParam As Long, _
                  ByVal lParam As Long)  As Long

Static nServer   As Long
Static hEcho     As Dword
Local  sBuffer   As String
Local  sPacket   As String

  Select Case wMsg

    Case %WM_INITDIALOG
        nServer = FreeFile ' получаем свободный номер файла
        Tcp Open Server Port Prt As nServer TimeOut TimOut  'открываем серверный порт
          If Err Then
              sBuffer = "Couldn't create socket!"  'ошибка нельзя создать сокет
          Else
              Tcp Notify nServer, Accept To hDlg As %TCP_ACCEPT  'задаем сообщение которое уведомит о приходе данных
              sBuffer = "Connected to Port 999"
          End If
        hEcho = %INVALID_SOCKET


    Case %TCP_ACCEPT
        Select Case Lo(Word, lParam)

           Case %FD_ACCEPT    'сокет может создать новую связь
               hEcho = FreeFile
               Tcp Accept nServer As hEcho  'Примите поступающую просьбу о связи из определенного TCP/IP порта.
               Tcp Notify hEcho, Recv Close To hDlg As %TCP_ECHO  'Определите какое TCP/IP событий сгенерирует сообщение уведомление %TCP_ECHO


        End Select
           Function = 1


   Case %TCP_ECHO
      Select Case Lo(Word, lParam)

        Case %FD_READ  ' Данные прочитаны из сокета.
            If hEcho <> %INVALID_SOCKET Then
                ' Выполнить приемник-цикл до тех пор пока есть данные (т.е., до конца потока)
                sBuffer = ""
                sPacket = ""

                Do
                  Tcp Recv hEcho, 8192, sBuffer 'читаем данные в переменную sBuffer
                  sPacket = sPacket + sBuffer
                  Loop Until sBuffer = "" Or IsTrue Eof(hEcho) Or IsTrue Err 'продолжаем читать до тех пор, пока sBuffer не вернет пустое значение


                 'сохраняем принятый файл на диск
                 Local hFile As Long
                 hFile=FreeFile
                 Open "1.zip" For Binary As hFile
                   Put$ hFile, sPacket
                 Close hFile

                 sPacket="" 'обнуление буфера
                 Tcp Print hEcho, "ok" 'ответ клиенту, что его файл принят

               Else

            End If

        Case %FD_CLOSE 'Сокет закрыт
            Tcp Close hEcho
            hEcho = %INVALID_SOCKET

      End Select
        Function = 1
End Select
End Function

'-----------------------------------------------------------------------
CallBack Function  DlgCallback()
  TcpProc CbHndl,CbMsg, CbWParam,CbLParam 'перенаправляем вызов в функцию TcpProc
End Function

'-----------------------------------------------------------------------
'Создаем окно обработки TCP сообщений
Function ShowTcpWindow() As Long
Local hDlg As Dword
Dialog New 0, "",,, 300, 100,, To hDlg
Dialog Show State hDlg, %SW_SHOW
Dialog Show Modal hDlg  , Call DlgCallback
End Function
'-----------------------------------------------------------------------

Function WinMain ( _
         ByVal  hInstance   As Dword, _
         ByVal  hPrevInst   As Dword, _
         ByVal  lpszCmdLine As Asciiz Ptr, _
         ByVal  nCmdShow    As Long ) As Long

  Prt=999         'задаем номер порта
  TimOut=5000     '5 сек тайм-аут
  ShowTcpWindow()
End Function   



Клиент:


Код: Выделить всё
#Compile Exe
#Dim All


Function tcp_send (ByVal Serv As String, ByVal prt As Dword, ByVal Tmout As Dword, ByVal txt As String) As String
    Local nSocket As Long
    Local sBuffer As String
    Local sPacket As String

    Tcp Open Port prt At Serv As nSocket TimeOut Tmout
    If Err Then
        Function = "Error opening port client: " + Str$(Err)
        Exit Function
    End If

    Tcp Print nSocket, txt; 'послыка данных серверу

    ErrClear
    'ждем потверждение от сервера, что он принял файл
    Do
        Tcp Recv nSocket, 1024, sBuffer
         sPacket = sPacket + sBuffer
    Loop Until sBuffer = "" Or IsTrue Eof(nSocket) Or IsTrue Err
   
     If sPacket="ok" Then
         MsgBox "Данные приняты!"
     End If


    If Err Then
        Function = "Error client" + Str$(Err) 'ошибка на стороне клиента
    Else
        Function = "Data:" + $CrLf + sPacket
    End If

    Tcp Close nSocket


End Function


Function PBMain () As Long
Local txt As String
   Open "test.zip" For Binary As 1  'загружаем файл с диска в переменную
      Get$ 1,Lof(1),txt
   Close 1

   Call  tcp_send ( "12.11.14.52",999, 60000, txt)

End Function

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 26.01.2007 (Пт) 10:06

Вообщем с битыми архивами разобрался, это оказался мой глюк, точнее кода который их обрабатывал. Теперь все передается без ошибок. Осталось понять почему размер буфера влияет на корректность принимаемы файлов.



Ничего там не понял. Может объяснишь в чем проблема, в двух словах?

volo
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 142
Зарегистрирован: 10.12.2004 (Пт) 11:18
Откуда: Soviet Union

Сообщение volo » 26.01.2007 (Пт) 10:35

ANDLL писал(а):Сколь редкий бред вы говорите...


Да в том то и дело, что бредом то и не пахнет.
Я говорил о передаче изоражений "custom" формата, а ля "img.spf"
изображения выкладывались Unix сервере.

При загрузке через любой вариант, формат типа spf интерпретировался как текстовый, jpg естественно интерпретировался как двоичный - нормально. На счет зипа думаю тут альтернатив не должно быть он должен интерпретироваться как двоичный.

Я кончено могу обломать, выложив на сервер для загрузки img.spf, который придет именно "битым", но не хочется тратить время на бесполезные доказательства "не понятно кому" и без всякой пользы.

ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.01.2007 (Пт) 11:09

volo
Ты вообще про какой протокол? Смею предположить по посту, что о HTTP.
Так вот, а автор про TCP.
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

volo
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 142
Зарегистрирован: 10.12.2004 (Пт) 11:18
Откуда: Soviet Union

Сообщение volo » 26.01.2007 (Пт) 13:31

ANDLL писал(а):volo
Ты вообще про какой протокол? Смею предположить по посту, что о HTTP.
Так вот, а автор про TCP.



Описанный эффект наблюдался при использовании
HTTP c TCP надстройкой (клиентская часть загрузки), и при использовании URLDownloadToFile

Не помню точно - летел 1 или 2 байта, кажется 0A0D

Из старых исходников нашел кусок клиентской части
Код: Выделить всё
FUNCTION loadfileTCP(sfile AS STRING)   AS LONG
    ON ERROR GOTO error_tcp
    LOCAL Buffer         AS STRING
    LOCAL JPEGLIB        AS STRING
    LOCAL hdlgtcp        AS LONG
    LOCAL t              AS LONG
    LOCAL SPF_LEN        AS LONG

    LOCAL aname          AS STRING
    LOCAL SERVER_PVD     AS STRING
    LOCAL SPF            AS STRING
    LOCAL FLAG           AS LONG  ' 0 - SPF, 1 - WAV, MID
    LOCAL a              AS STRING
    a = UCASE$(RIGHT$(TRIM$(sfile),4))
    ! mov OS_MASTER,1
    IF  a = ".SPF" OR a = ".JPG" OR a = "JPEG" THEN
        ! mov FLAG,0
    ELSE
        ! mov FLAG,1
    END IF

IF TRIM$(cashe(TOUR.idx)) = "" OR FLAG = 1 THEN
        !;************************************************>
    IF INSTR(sfile,"http://") = 0 THEN 'URL
            IF DIR$(sfile)  = "" THEN error_tcp
            OPEN sfile FOR BINARY AS 4
                GET$ 4,LOF(4),JPEGLIB
            CLOSE 4
            CONTROL SET TEXT hdlg, 8813,"SPF ready"
    ELSE
        !;************************************************>

        aname = REMOVE$(TRIM$(sfile),"http://")
        SERVER_PVD = EXTRACT$(aname,"/")

        TCP OPEN PORT 80 AT SERVER_PVD AS #1 TIMEOUT 10000
        IF ERRCLEAR<>0 THEN GOTO error_tcp
        TCP PRINT #1,"GET " & TRIM$(sfile) & " HTTP/1.0"
        TCP PRINT #1,""

        Buffer$ = SPACE$(1024)
        ! mov t,0
        DO
            TCP RECV #1, %TCPBUFFER, Buffer
                IF t=0 THEN
                   t = VAL(REMAIN$(Buffer,"Content-Length:"))
                   SPF_LEN = t
                   t = 1
                END IF

            CONTROL SET SIZE hdlg, 8812,(224 * LEN(JPEGLIB))/SPF_LEN ,7
            IF LEN(Buffer) = 0 THEN EXIT DO
            JPEGLIB = JPEGLIB + Buffer
            IF FLAG = 0 THEN aname = "SPF = " ELSE aname = "SND = "
        CONTROL SET TEXT hdlg,8813,"load " & aname & FORMAT$(LEN(JPEGLIB)) & " kb"
        DIALOG DOEVENTS
        LOOP
        CONTROL SET SIZE hdlg, 8812,0,7
        CONTROL SET TEXT hdlg, 8813,"SPF ready"
        TCP CLOSE #1
        IF FLAG = 1 THEN JPEGLIB = REMAIN$(JPEGLIB,$CRLF & $CRLF)
    END IF
ELSE
      JPEGLIB = cashe(TOUR.idx)
END IF

'     ...........................

EXIT FUNCTION
'----------------------------------------
error_tcp:
     TCP CLOSE #1
     MSGBOX $ERR_T & " ERR FLAG =" & STR$(FLAG), %MB_ICONERROR, $ERR_S
     CONTROL SET SIZE hdlg,8812,0,7
     CONTROL SET TEXT hdlg,8813,$ERR_T
END FUNCTION
'_____________________________________________________________



ANDLL
Великий гастроном
Великий гастроном
Аватара пользователя
 
Сообщения: 3450
Зарегистрирован: 29.06.2003 (Вс) 18:55

Сообщение ANDLL » 26.01.2007 (Пт) 13:40

volo
Ты все еще не врубился в разницу между передачей файлов по HTTP и тем что здесь обсуждалось?
Гастрономия - наука о пище, о ее приготовлении, употреблении, переварении и испражнении.
Блог

PBDN
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 21.10.2006 (Сб) 22:10

Сообщение PBDN » 26.01.2007 (Пт) 14:10

jangle писал(а):


Ничего там не понял. Может объяснишь в чем проблема, в двух словах?


Когда работается на прямую с ТСР с использованием recv
буффер должен быть в пределах текущего MTU - ethrnet frame

чтобы получить размер буффера ТСР стека используйте
Код: Выделить всё
P.S.
to get current size of ethernet block size or how it usually calls - MTU
use getsocketopt(sock, SOL_SOCKET, SO_MAX_MSG_SIZE, optVal, sizeof(int));

volo
Продвинутый пользователь
Продвинутый пользователь
Аватара пользователя
 
Сообщения: 142
Зарегистрирован: 10.12.2004 (Пт) 11:18
Откуда: Soviet Union

Сообщение volo » 26.01.2007 (Пт) 14:30

ANDLL писал(а):volo
Ты все еще не врубился в разницу между передачей файлов по HTTP и тем что здесь обсуждалось?


Башку переклинило фразой "на другой комп приходят битыми"
Вспомнил о своем, о старом.

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 26.01.2007 (Пт) 15:32

Когда работается на прямую с ТСР с использованием recv
буффер должен быть в пределах текущего MTU - ethrnet frame


Спасибо! :)

А примера нет, как использовать getsocketopt ?

PBDN
Обычный пользователь
Обычный пользователь
 
Сообщения: 59
Зарегистрирован: 21.10.2006 (Сб) 22:10

Сообщение PBDN » 27.01.2007 (Сб) 2:47

jangle писал(а):А примера нет, как использовать getsocketopt ?


С собой приера нет, посмотрите здесь
http://forum.sources.ru/index.php?showt ... getsockopt
ИМХО неплохо расписанно.

и букварь по сети и протоколам здесь

jangle
Википедик
Википедик
Аватара пользователя
 
Сообщения: 3013
Зарегистрирован: 03.06.2005 (Пт) 12:02
Откуда: Нидерланды

Сообщение jangle » 29.01.2007 (Пн) 9:47

С собой приера нет, посмотрите здесь
http://forum.sources.ru/index.php?showt ... getsockopt
ИМХО неплохо расписанно.


спасибо! Попробую разобраться..


Вернуться в Power Basic

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 55

    TopList