none
Передача файлов через TCP склиент RRS feed

  • Вопрос

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

    'Отправляем файл...
      SendFileBytes(My.Computer.FileSystem.ReadAllBytes(UpLoad(i)))))

    'Процедура отправления серверу файла
    Public Sub SendFileBytes(ByVal data() As Byte)
    SyncLock My.Forms.General.YouClient.GetStream
    Dim writer As New IO.StreamWriter(My.Forms.General.YouClient.GetStream)
    writer.Write(data)
    writer.Flush()
    End SyncLock
    End Sub

    А в сервере принимаем...


    Private OneClient As TcpClient
    Private readBuffer(READ_BUFFER_SIZE) As Byte

    Public Event LineReceived(ByVal sender As UserConnection, ByVal Data As String)

    'Инициализируем новое подключение для дальнейшей работы
    Public Sub New(ByVal NewClient As TcpClient)
    Me.OneClient = NewClient

    'Начинаем асинхронное чтение с записью в readBuffer
    Me.OneClient.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
    End Sub

      ' асинхронное чтение с клиентом
    Private Sub StreamReceiver(ByVal ar As IAsyncResult)
    Dim BytesRead As Integer
    Dim strMessage As String

    Try
        SyncLock OneClient.GetStream
    'Заканчиваем асинхронное чтение и считаем кол-во байт
    BytesRead = OneClient.GetStream.EndRead(ar)
    End SyncLock

    'Если это файл, ненужно его преобразовывать в текст, схраняем...
    If Me.UP = True Then
    My.Computer.FileSystem.WriteAllBytes(My.Computer.FileSystem.CurrentDirectory & _
    "\" & Me.FileUP, readBuffer, True)
        Else

    strMessage = Encoding.UTF8.GetString(readBuffer, 0, BytesRead - 1)

        RaiseEvent LineReceived(Me, strMessage) 'Вызываем обработку комманд
    End If

        SyncLock OneClient.GetStream
    'Начинаем новое асинхронное чтение
    OneClient.GetStream.BeginRead(readBuffer, 0, READ_BUFFER_SIZE, AddressOf StreamReceiver, Nothing)
    End SyncLock
    Catch e As Exception
      End Try

    End Sub

     

    Но после отправки любых файлов, вместо них получаются только 256 байтные. В чем причина? Может не так отправлять нужно? Помогите пожалуйста, если не трудно, небольшой пример как это правильно сделать. Заранее спасибо!

    13 февраля 2011 г. 21:12

Ответы

  • В любом случае передаются и принимаются байты, лишние преобразования думаю не нужны. Про прием файла - вам нужно либо дописывать каждую пачку принятых байт в конец файла, либо аккумулировать принятые байты в какой-нибудь локальной переменной, а после записывать ее всю с помощью WriteAllByte.
    Для связи [mail]
    • Помечено в качестве ответа Siompc 15 февраля 2011 г. 11:07
    15 февраля 2011 г. 10:42

Все ответы

  • Пробую так, в клиенте представляю файл ввиде массива байт

     

    SendFileBytes(My.Computer.FileSystem.ReadAllBytes("ПУТЬ К ФАЙЛУ"))

    'Процедура отправления серверу файла
    Public Sub SendFileBytes(ByVal data() As Byte)
    SyncLock My.Forms.General.YouClient.GetStream
    Dim writer As New IO.StreamWriter(My.Forms.General.YouClient.GetStream)
    Dim i As UInteger
       For i = 0 To data.Length - 1
       writer.Write(data(i))
    Next
       writer.Flush()
    End SyncLock
    End Sub

     

     

    А в сервере просто принимаем эти байты и дописываем в файл с каким то именем:

    ' асинхронное чтение с клиентом
    Private Sub StreamReceiver(ByVal ar As IAsyncResult)
    Dim BytesRead As Integer
    Dim strMessage As String

    Try
    'SyncLock что бы другой поток не смог использовать это в тоже самое время
    SyncLock OneClient.GetStream
    'Заканчиваем асинхронное чтение и считаем кол-во байт
    BytesRead = OneClient.GetStream.EndRead(ar)
    End SyncLock

       My.Computer.FileSystem.WriteAllBytes(My.Computer.FileSystem.CurrentDirectory & _
    "\" & Me.FileUP, readBuffer, True)

     

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

    14 февраля 2011 г. 9:43
  • Похоже никто не поможет... Ну хоть знает кто нибудь  почему при записи принятых байт в файле, заместо изначальных "Пробный текст..." получается System.Byte[]...
    15 февраля 2011 г. 8:39
  • все в цифром мире - массив байт.

    для конвертации массива в строку воспользуйтесь следующим примером (кодировку только правильную выберите)

    // C# to convert a byte array to a string.
    byte [] dBytes = ...
    string str;
    System.Text.UTF8Encoding enc = new System.Text.UTF8Encoding();
    str = enc.GetString(dBytes);
    
    
    15 февраля 2011 г. 9:08
  • Да, но я так уже деалал. Только при переводе в строку файл увеличивается при передаче в размере почти в 2 раза.
    15 февраля 2011 г. 9:31
  • Попробую еще раз. Но как потом строку перевести обратно в массив байт?
    15 февраля 2011 г. 9:36
  • Вот нашел это:

     

    'Visual Basic .NET Преобразование строки в массив байтов и обратно
    'Для преобразования строки в массив байтов и обратно используйте следующий код:

    Dim MyText As String = "Строка текста"
    Dim Encoding As New System.Text.UTF8Encoding(), Bytes() As Byte
    'Преобразование строки в массив байт
    Bytes = Encoding.GetBytes(MyText)

    'Преобразование массива байт в строку
    MyText = Nothing
    MyText = Encoding.GetString(Bytes)

     

    Здесь используется кодировка UTF8Encoding. А какая кодировка используется в файлах?

    15 февраля 2011 г. 9:43
  • Тут ошибка в

    Dim writer As New IO.StreamWriter(My.Forms.General.YouClient.GetStream)
    writer.Write(data)

    StreamWriter.Write не принимает массив байт, он вызывает неявно ToString для него и передает строку System.Byte[]. Для передачи байтов используйте сразу метод Write для GetStream


    Для связи [mail]
    15 февраля 2011 г. 9:55
  • GetSteam.Write('массив байт') то есть так? Не совсем понял.. напиши пожалуйста.
    15 февраля 2011 г. 10:04
  • data - массив байт

    Dim writer As NetworkStream = client.GetStream()
    writer.Write(data, 0, data.Length)

    Для связи [mail]
    15 февраля 2011 г. 10:11
  • Огромное спасибо! еще пара вопросов и все. сервер принимать будет этот массив в тот же readBuffer? и его можно будет просто дописать в файл WriteAllByte? и можно еще сделать так, брать массив, преобразовать его в строку с кодировкой любой, отправить, а сервер по этой кодировке переведет строку в байты и допишет их в файл. так работать будет? и как лучше, переводить в строку или слать массив?
    15 февраля 2011 г. 10:19
  • В любом случае передаются и принимаются байты, лишние преобразования думаю не нужны. Про прием файла - вам нужно либо дописывать каждую пачку принятых байт в конец файла, либо аккумулировать принятые байты в какой-нибудь локальной переменной, а после записывать ее всю с помощью WriteAllByte.
    Для связи [mail]
    • Помечено в качестве ответа Siompc 15 февраля 2011 г. 11:07
    15 февраля 2011 г. 10:42