На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> Проблема при передачи файлов по сети (TcpClient/TcpListener)
    Доброго времени суток уважаемые форумчане. Возникла тут у меня проблемка, а решить не выходит т.к. не понятно где вообще собака зарыта) Дело в том, что мое клиент-серверное приложение прекрасно коннектится и передает файлы, но только если запускать и сервер и клиент на локальном компьютере. А вот при попытке работы через интернет или по локальной сети происходит непонятно что(пробовал и так, и так. Благо имею две машины, объединенные в сеть). Соединение происходит, сервер получает от клиента имя файла и его размер, выводит их в консоль и даже создает файл с соответствующим именем в своей директории. На этом клиент намертво зависает и созданный сервером файл остается пустым, т.е. само содержимое файла не передается. Не могу понять где вообще искать ошибку. По идее, если на локальной машине все работает нормально, значит код осуществляющий передачу данных (который наиболее проблематичен для меня) написан нормально, а значит проблема в коде соединения? Можете ли вы что-нибудь подсказать мне по этому поводу?

    Могу выложить исходный код, если конечно кто-нибудь захочет его смотреть...
      Давай код.
        Сервер:
        Скрытый текст
        ExpandedWrap disabled
          static void Main(string[] args)
                  {
                      int bufSize = 100 * 1024; //в kB; проследить, чтоб совпадал с клиентским буффером.
                      int totLen, length;
                      TcpListener clientListener = null;
                      Byte[] bytes = new Byte[4];
                      bool flag;
                      byte[] clientInfoData = new byte[7];
                      string path = @"D:\Projects\";
           
                      try
                      {
           
                          IPAddress ip = IPAddress.Parse("127.0.0.1");
                          clientListener = new TcpListener(ip, 34567);
                          clientListener.Start();
                          Console.WriteLine("Начал слушать клиентов");
           
                          flag = true;
           
                          while (flag)
                          {
                              TcpClient client = clientListener.AcceptTcpClient();
                              Console.WriteLine("Произошло подключение");
                              totLen = 0; length = 0;
                              int i; // размер принятого пакета в байтах
                              NetworkStream NetStream = client.GetStream();
                              StreamReader sr = new StreamReader(NetStream);
           
                              string btnResult = sr.ReadLine();
                                  Console.WriteLine("Прием файла");
                                  string nameFile = sr.ReadLine(); //имя принимаемого файла
           
                                  if (!Directory.Exists(path))
                                  {
                                      Directory.CreateDirectory(path);
                                  }
                                  BinaryWriter bWriter = new BinaryWriter(File.Open(path + "\\" + nameFile, FileMode.Create));
                                  string s = sr.ReadLine(); // считываем размер файла из потока
           
                                  Console.WriteLine("Получаем файл {0} размером {1} байт.", nameFile, s);
                                  length = Convert.ToInt32(s); //размер передаваемого файла.
                                  Byte[] big_arr = new Byte[bufSize]; //буффер для принятие пакетов с файлом.
           
                                  bool flag2 = true; // флаг корректного принятия пакета
                                  int messSize = 0; // размер передаваемого пакета (должен быть равен размеру принятого пакета)
                                  int t = 0; //счетчик пакетов
                                  while (flag2)
                                  {
                                      NetStream.Read(bytes, 0, 4);
                                      messSize = BitConverter.ToInt32(bytes, 0);// принять размер передаваемого пакета
                                      NetStream.Read(bytes, 0, 4);
                                      t = BitConverter.ToInt32(bytes, 0); // принять номер пакета
                                      Console.Write(".");
                                      // принимать данные до тех пор, пока не совпадет размер принятого и переданного пакетов
                                      do
                                      {
                                          i = NetStream.Read(big_arr, 0, big_arr.Length);
                                          if (i == 0) // если ничего не передано
                                          {
                                              break;
                                          }
                                          if (i != messSize) // не совпало - шлем ответ с ошибкой
                                          {
                                              clientInfoData = Encoding.ASCII.GetBytes("FAIL");
                                              NetStream.Write(clientInfoData, 0, clientInfoData.Length);
                                          }
                                      }
                                      while (i != messSize);
           
                                      totLen += i; // размер принятых данных += размер буффера
                                      bWriter.Write(big_arr, 0, i);
                                      bWriter.Flush();
                                      System.Threading.Thread.Sleep(1);
           
                                      clientInfoData = Encoding.ASCII.GetBytes("SUCCESS");
                                      NetStream.Write(clientInfoData, 0, clientInfoData.Length);// шлем ответ с подтверждением успеха
           
                                      if (totLen == length)//если файл приняли полностью
                                      {
                                          flag2 = false;
                                          Console.WriteLine("Все ok");
                                      }
                                  }
                                  bWriter.Close();
                                  bWriter.Dispose();


        Клиент:
        Скрытый текст
        ExpandedWrap disabled
          private void button1_Click(object sender, EventArgs e)
                  {
                      int bufSize = 100 * 1024;//  размер буффера в kB;проследить, чтоб совпадал с серверным буффером.
                      int progress = 0; // % выполнения
                      try
                      {
                          OpenFileDialog ofd = new OpenFileDialog();
                          if (ofd.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                          {
                              TcpClient eclient = new TcpClient("localhost", 34567);
                              NetworkStream writerStream = eclient.GetStream();
                              BinaryReader bReader = new BinaryReader(new FileStream(ofd.FileName, FileMode.Open));
                              bReader.BaseStream.Seek(0, SeekOrigin.Begin);
           
                              StreamWriter TCPStream = new StreamWriter(writerStream);
                              // посылаем имя файла
                              string nameFile = Path.GetFileName(ofd.FileName);
                              TCPStream.WriteLine(nameFile);
                              TCPStream.Flush();
                              System.Threading.Thread.Sleep(1);
                              // посылаем размер файла
                              int lengthFile = (int)(new FileInfo(ofd.FileName).Length);
                              TCPStream.WriteLine(lengthFile.ToString());
                              TCPStream.Flush();
                              System.Threading.Thread.Sleep(1);
           
                              StreamBuffer buf = new StreamBuffer(bufSize, writerStream);
                              int sentDataSize = 0; // размер переданных данных
                              int i = 0; // номер передаваемого пакета
                              while (sentDataSize < lengthFile)
                              {
                                  if (sentDataSize + buf.BufferSize <= lengthFile)
                                  {
                                      i++;
                                      buf.buffer = bReader.ReadBytes(buf.BufferSize);
                                      sentDataSize += buf.BufferSize;
                                      progress = (int)(((float)sentDataSize / lengthFile) * 100);
                                      buf.SendAttempt(i);
                                      textBox1.Text = new StringBuilder().AppendFormat("Отправил пакет размером {0}, {1}%.", bufSize, progress).ToString();
                                      textBox1.Refresh();
                                  }
                                  else
                                  {
                                      i = 0;
                                      //последний пакет может иметь меньшую длину.
                                      int lastLength = lengthFile - sentDataSize;
                                      StreamBuffer endData = new StreamBuffer(lastLength, writerStream);
                                      bReader.Read(endData.buffer, 0, endData.BufferSize);
                                      sentDataSize = lengthFile;
                                      progress = 100;
                                      endData.SendAttempt(i);
                                      textBox1.Text = new StringBuilder().AppendFormat("Отправил последний пакет размером {0}, {1}%", lastLength, progress).ToString();
                                      writerStream.Flush();
                                      textBox1.Refresh();
                                  }
                              }
                              writerStream.Close();
                              TCPStream.Close();
                              TCPStream.Dispose();
                              bReader.Close();
                          }
                      }
                      catch (ArgumentNullException t)
                      {
                          StringBuilder temp = new StringBuilder().AppendFormat("ArgumentNullException: {0}", t);
                          MessageBox.Show(temp.ToString());
                      }
                      catch (SocketException t)
                      {
                          StringBuilder temp = new StringBuilder().AppendFormat("SocketException: {0}", t);
                          MessageBox.Show(temp.ToString());
                      }
                  }


        Класс StreamBuffer (используется в клиенте):
        Скрытый текст
        ExpandedWrap disabled
          namespace StreamBuf
          {
              class StreamBuffer
              {
                  public int BufferSize { get { return _bufSize; } }
                  public Byte[] buffer;
                  public bool sendResult = false;
                  NetworkStream _stream = null;
                  int _bufSize = 0;
                  byte[] _bufSizeBytes;
                  byte[] _PackNo = new byte[4];
           
                  public StreamBuffer(int size, NetworkStream stream)
                  {
                      buffer = new Byte[size];
                      _stream = stream;
                      _bufSize = size;
                      _bufSizeBytes = BitConverter.GetBytes((int)size);
                  }
                  public void SendAttempt(Int32 i)
                  {
                      _stream.Write(_bufSizeBytes, 0, _bufSizeBytes.Length);
                      _stream.Flush();
                      System.Threading.Thread.Sleep(1);
                      _PackNo = BitConverter.GetBytes(i);
                      _stream.Write(_PackNo, 0, _PackNo.Length);
                      _stream.Flush();
                      System.Threading.Thread.Sleep(1);
           
                      do
                      {
                          _stream.Write(buffer, 0, _bufSize);
                          _stream.Flush();
                          System.Threading.Thread.Sleep(1);
                          //подтверждение успешного получения
                          byte[] receiveData = new byte[7];
                          int len = _stream.Read(receiveData, 0, 7);
                          if (Encoding.ASCII.GetString(receiveData, 0, len) == "SUCCESS")
                              sendResult = true;
                      } while (!sendResult);
                      sendResult = false;
                  }
              }
          }

          michspar, передумал?)
            Я сокетами мало занимался, но меня смущает строчка

            IPAddress ip = IPAddress.Parse("127.0.0.1");

            в Вашем сервере. Этот IP чисто локальный. Из сети он не виден. Попробуйте подставить настоящий. Это раз.

            И второе - Вы пытались пустить клиента под отладкой?
              Цитата hd44780 @
              Я сокетами мало занимался, но меня смущает строчка

              IPAddress ip = IPAddress.Parse("127.0.0.1");

              в Вашем сервере. Этот IP чисто локальный. Из сети он не виден. Попробуйте подставить настоящий.

              Я бы с этого начал.
              1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
              0 пользователей:


              Рейтинг@Mail.ru
              [ Script execution time: 0,0270 ]   [ 15 queries used ]   [ Generated: 8.11.24, 22:59 GMT ]