2012-07-01 2 views
1

Я пишу приложение для отправки и получения некоторых данных на сервер и с него. Мне нужно сделать соединение, прежде чем отправлять некоторые данные, и нужно держать его открытым, чтобы пользователь мог непрерывно отправлять данные. Пользователь может закрыть соединение в любое время, нажав кнопку разъединения. Я создал 2 кнопки, один для подключения и один для отключения. код позади кнопки Disconnect, как показано ниже: -TcpClient Connection

private void button1_Click(object sender, EventArgs e) 
    { 
     if (tcpclnt.Connected) 
     { 
      tcpclnt.Client.Disconnect(false); 
      stm.Close(); 
     } 
     else 
     { 
      MessageBox.Show("Not Connected"); 
     } 
    } 

код позади подключения кнопки, как показано ниже: -

public ASCIIEncoding asen = new ASCIIEncoding(); 
    public TcpClient tcpclnt = new TcpClient(); 
    public NetworkStream stm; 

    private void Connect_Click(object sender, EventArgs e) 
    { 
     if (!tcpclnt.Connected) 
     {     
      tcpclnt.Connect("XX.XX.XX.XX", 5500); 
      MessageBox.Show("Connected to server"); 


      stm = tcpclnt.GetStream(); 

      string sysname = "000B0000" + SystemName.Text.ToString(); 
      byte[] sys1 = asen.GetBytes(sysname); 
      sys1[0] = 0; sys1[1] = 0; 
      sys1[2] = 0; sys1[3] = 0xB; 
      sys1[4] = 0; sys1[5] = 0; 
      sys1[6] = 0; sys1[7] = 0; 
      try 
      { 
       stm.Write(sys1, 0, sys1.Length); 
      } 
      catch (Exception ex) 
      { 
       MessageBox.Show(ex.ToString()); 
       MessageBox.Show("Error in Sending data"); 
      } 
      if (stm.DataAvailable) 
      { 
       try 
       { 
        byte[] bb = new byte[600]; 
        int k = 8;       
        k = stm.Read(bb, 0, bb.Length); 
        string value = ASCIIEncoding.ASCII.GetString(bb, 8, k - 8); 
        MessageBox.Show(value.ToString()); 
       } 
       catch (Exception ex) 
       { 
        MessageBox.Show(ex.ToString()); 
        MessageBox.Show("Error in Reading data"); 
       } 
      }     
     } 
     else { 
       MessageBox.Show("Already Connected"); 
     } 
    } 

Теперь, когда я нажимаю на кнопку Отключить и снова нажмите на кнопку подключения, он бросает исключение в строке tcpclient.connect. Я не понимаю, почему и как я могу это решить.

+0

Можете ли вы упомянуть, какое исключение вы столкнулись? – ZafarYousafi

ответ

0

Ваш вызов .Disconnect() должен иметь значение true в качестве параметра, позволяющего повторное использование. В настоящее время вы говорите, что гнездо запрещает повторное подключение. See here для документации.

+0

не работает ... дайте ошибку на tcpclient.connect строке, говоря – Adir

0

Не эксперт по этой теме, но я думаю, что возможным решением было бы изящно закрыть соединение, используя tcpclnt.Close(). Если вы этого не сделаете или пусть сборщик мусора сделает это беззастенчиво, то вы не сможете снова подключиться (я думаю). Закройте поток, затем закройте tcpclnt, а не отключите.

tcpclnt.GetStream().Close(); 
tcpclnt.Close(); 

Кроме того, не используйте tcpclnt.Connected для проверки наличия соединения. Просто просто закройте его.

EDIT

выше не работает. Я не знаю, как повторно использовать сокет. Вот как я получил это, чтобы работать ...

private void DisconnectButton_Click(object sender, EventArgs e) 
{ 
    tcpclnt.Close(); 
    tcpclnt = new TcpClient(); 
} 

Вы упомянули, что повторное создание объекта создает дополнительные потоки. Это может быть правдой, поскольку я не уверен, как проверить это. Я открыл монитор ресурсов Windows и просмотрел количество потоков для приложения, и каждый раз он не показывал дополнительный поток.

+0

, что тоже не работает .... на самом деле проблема tcpclnt.Connect дает проблему каждый раз. Я могу сделать одно, что я могу определить «public TcpClient tcpclnt = new TcpClient();» каждый раз, когда я пытаюсь подключиться, но кажется, что создаст много открытых потоков .... если пользователь нажимает кнопку подключения 10 раз, тогда он создаст 10 открытых подключений .... (Не уверен в этой части, поскольку я новичок в этой технологии). PLease предложит, чтобы это был хороший способ сделать это. – Adir

+0

Будьте осторожны, закрывая потоки и соединения, как это, потому что они тесно связаны с гнездом, поэтому в случае повторного использования сокета вещи могут быть не столь изящными. По какой-то причине библиотека TCP в C# довольно ... winie. Просто будьте осторожны :) –

+0

Да, похоже, это сработало, спасибо Тео :-) – Adir