На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> вопрос по сокетам
    Заранее спасибо!

    Господа подскажите

    вот такая проблемма:

    Я создал серверную часть и она вроде пашет, т.е. я принимаю соединение и пересылаю сообщения туда и обратно
    метод Acept закинул в поток, также и метод receive закинут в поток

    вот код класа:
    ExpandedWrap disabled
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;
       
      using System.Net;
      using System.Net.Sockets;
      using System.Threading;
      using System.Windows.Forms;
       
      namespace Сервер_3
      {
              
          class СерверСокет
          {
              /// <summary>
              /// Хост сервера
              /// </summary>
              public static IPHostEntry S_Host;
       
              /// <summary>
              /// IP сервера
              /// </summary>
              public static IPAddress S_IP;
       
              /// <summary>
              /// Конечная точка сервера
              /// </summary>
              public static IPEndPoint S_EndPoin;
       
              /// <summary>
              /// Cокет Сервера
              /// </summary>
              public static Socket S_Socket;
       
              /// <summary>
              /// Вспомогательный сокет
              /// </summary>
              public static Socket H_Socket;
       
          
              /// <summary>
              /// Возвращает состояние соединения
              /// </summary>
              public static bool IsConnected = false;
       
              /// <summary>
              /// Входящее Сообщение
              /// </summary>
              public static string In_Message = "";
       
              
      ///------------------------------------------------------------------------------------------------------- ///
       
              /// <summary>
              /// Деструктор сервера
              /// </summary>
              public static void ЗакрытьСерверСокет()
              {
                  try
                  {
                      /// Обрываем соединения
                      S_Socket.Shutdown(SocketShutdown.Both);
       
                      /// Закрываем сокет
                      S_Socket.Close();
       
                      /// Обрываем соединения
                      H_Socket.Shutdown(SocketShutdown.Both);
       
                      /// Закрываем сокет
                      H_Socket.Close();
                  }
                  catch { }
       
              }
       
              /// <summary>
              /// Создает сокет
              /// </summary>
              /// <param name="Port"> Порт каторый будет использоваться для пересылке данных</param>
              public static void CreateServer(int Port)
              {
                  S_Host = Dns.GetHostEntry(Dns.GetHostName());
                  S_IP = S_Host.AddressList[0];
                  S_EndPoin = new IPEndPoint(S_IP, Port);
       
                  try
                  {
                      /// Создаем сокет
                      S_Socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
                  }
                  catch (SocketException error)
                  {
                      /// 10061 - порт подключения занят/закрыт
                      if (error.ErrorCode == 10061)
                      {
                          MessageBox.Show("Порт подключения закрыт или введен не веррный порт.\r Приложение будет остановленно", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
                          Application.Exit();
                      }
                  }
       
              }
              
              /// <summary>
              /// Количество ожидаеммых подключений
              /// </summary>
              public static int ДлинаОчереди;
              /// <summary>
              /// Запускает сервер, сервер ожидает первое подключение клиента
              /// </summary>
              public static void StartServer()
              {
                  try
                  {
                      /// связываем удаленную точку с сокетом
                      S_Socket.Bind(S_EndPoin);
       
                      /// запускаем сканер подключений
                      S_Socket.Listen(ДлинаОчереди);
       
                      // начинаем "прослушивать" подключения
                      while (true)
                      {
                          try
                          {                        
                              H_Socket = S_Socket.Accept();
                              
                              /// если есть подключение
                              if (H_Socket.Connected)
                              {
                                  IsConnected = true;
                                  return;     /// как выход, поможет завершить поток
                              }
       
                              
                          }
                          catch { }
                                            
                      }
                  }
                  catch { }
              }
       
              /// <summary>
              /// Получаем сообщение от клиента
              /// </summary>
              /// <returns>Сообщение</returns>
              public static string GetMessage()
              {
                  string GetInformation = "";
       
                  byte[] GetBytes = new byte[1024];
                  int BytesRec = H_Socket.Receive(GetBytes);
       
                  GetInformation += Encoding.Unicode.GetString(GetBytes, 0, BytesRec);
       
                  return GetInformation;
              }
       
              /// <summary>
              /// Отправляем Сообщение клиенту
              /// </summary>
              /// <param name="Data"></param>
              public static void SendMessage(string Data)
              {
                  byte[] SendMsg = Encoding.Unicode.GetBytes(Data);
                  H_Socket.Send(SendMsg);
              }
       
              /// <summary>
              /// Сборщик входящих сообщений
              /// </summary>
              public static void ЖдемСообщение()
              {
                  while (true)
                  {
                      
                      /// даем время на отправку сообщения
                      Thread.Sleep(50);
       
                      /// забераем входящее сообщение
                      In_Message = GetMessage();
                      
                  }
              }
       
          
          }
      }


    А вод код интерфейса:
    ExpandedWrap disabled
      using System;
      using System.Collections.Generic;
      using System.ComponentModel;
      using System.Data;
      using System.Drawing;
      using System.Linq;
      using System.Text;
      using System.Windows.Forms;
       
      using System.Threading;
      using System.Net;
      using System.Net.Sockets;
       
       
      namespace Сервер_3
      {
          public partial class Сервер : Form
          {
       
              public Thread поток;
              public Thread поток_СканерСоединения;
              public Thread поток_СканерСообщения;
       
       
              public Сервер()
              {
                  InitializeComponent();
                            
              }
       
              private void btnConnect_Click(object sender, EventArgs e)
              {
                  try
                  {
                      СерверСокет.CreateServer(int.Parse(txtbxPort.Text));
                      this.Text = СерверСокет.S_IP.ToString();
       
                      lstbxChat.Items.Add("[БОТ]: Сервер созжан");
       
                  }
                  catch
                  {
                      lstbxChat.Items.Add("[БОТ]: Возникла ошибка при создании сервера");
                      return;
                  }
       
                  /// задаем длину очереди
                  СерверСокет.ДлинаОчереди = 10;
       
                  try
                  {
                      /// создаем поток который отслеживает за подключением клиента
                      поток = new Thread(new ThreadStart(СерверСокет.StartServer));
                      поток.Start();
       
                      lstbxChat.Items.Add("[БОТ]: Сервер запущен");
       
                      tmrScanConnect.Enabled = true;
                  }
                  catch
                  {
                      lstbxChat.Items.Add("[БОТ]: Неудается запустить сервер. Поток \"поток_ОжиданиеСоединения\" не создан");
                      return;
                  }
              }
       
              private void tmrScanConnect_Tick(object sender, EventArgs e)
              {
                  if (СерверСокет.IsConnected)
                  {
                      try
                      {
                          /// останавливаем поток
                          поток.Abort();
                                            
                      }
                      catch
                      {
                          lstbxChat.Items.Add("[БОТ]: Неудается завершить поток \"поток_ОжиданиеСоединения\"");
                          return;
                      }
       
                      try
                      {
                          /// запускаем поток на ожидание сообщения
                          поток = new Thread(new ThreadStart(СерверСокет.ЖдемСообщение));
                          поток.Start();
       
                          tmrScanMessage.Enabled = true;
                      }
                      catch
                      {
                          lstbxChat.Items.Add("[БОТ]: Неудается запустить поток \"поток_СканерСообщения\"");
                          return;
                      }
                      tmrScanConnect.Enabled = false;
                      lstbxChat.Items.Add("[БОТ]: Установленно соединение");
                  }
              }
       
              private void Сервер_Load(object sender, EventArgs e)
              {
                  IPHostEntry Host;
                  IPAddress IP;
                
                  Host = Dns.GetHostEntry(Dns.GetHostName());
                  IP = Host.AddressList[0];
       
                  txtbxIP.Text = IP.ToString();
       
              }
       
              private void btnSend_Click(object sender, EventArgs e)
              {
                  if (txtbxMessage.Text != "")
                  {
                      lstbxChat.Items.Add("<" + DateTime.Now.ToShortTimeString() + ">" + "[" + txtbxNik.Text + "]:" + txtbxMessage.Text);
                      СерверСокет.SendMessage("[" + txtbxNik.Text + "]:" + txtbxMessage.Text);
                  }
              }
       
              private void tmrScanMessage_Tick(object sender, EventArgs e)
              {
                  if (СерверСокет.In_Message != "")
                  {
                      lstbxChat.Items.Add("<" + DateTime.Now.ToShortTimeString() + ">" + СерверСокет.In_Message);
       
                      СерверСокет.In_Message = "";
                  }
              }
       
              private void Сервер_FormClosed(object sender, FormClosedEventArgs e)
              {
                  tmrScanMessage.Enabled = false;
       
                  /// останавливаем потоки
                  try
                  {
                     поток.Abort();
                     СерверСокет.ЗакрытьСерверСокет();
                  }
                  catch { }
                                      
                
                  Application.Exit();
                  
              }
       
          
          }
      }


    проблема в том, что когда я закрываю приложение, в деспетчере задачь приложение не закрывается :)
    т.е. вроде закрыл приложение (на мониторе окно приложения не видно), а в деспетчере задачь приложениен не закрыто


    я как понял когда я пишу:
    ExpandedWrap disabled
      H_Socket = S_Socket.Accept();


    и

    ExpandedWrap disabled
      int BytesRec = H_Socket.Receive(GetBytes);


    управление толи блокируется толи хз куда девается

    помогите решить эту траблу

    я вижу 3 выход:
    1) надо както останавливать прослушку сокета, когда я говорю "H_Socket = S_Socket.Accept();"
    и сканер новых сообщений, "int BytesRec = H_Socket.Receive(GetBytes);", что поможет мне закрыть поток

    2) либо както убить созданный мной поток, он создается в 2 местах :

    ExpandedWrap disabled
        /// создаем поток который отслеживает за подключением клиента
                      поток = new Thread(new ThreadStart(СерверСокет.StartServer));
                      поток.Start();

    ExpandedWrap disabled
                      /// запускаем поток на ожидание сообщения
                      поток = new Thread(new ThreadStart(СерверСокет.ЖдемСообщение));
                      поток.Start();

    3) надо както насильно закрыть приложение, так чтобы оно убилось в диспетчере задачь
    Сообщение отредактировано: yfvznjd -
      Спрячьте этот код и никому не показывайте :lool: . Убать кириллицу/транслит. Логику приложения, формы и сетевое взаимодействие растащить по абстракциям.
      По сабжу, потоку требуется выставить свойство IsBackground в true, а лучше использовать ThreadPool.QueueUserWorkItem
      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
      0 пользователей:


      Рейтинг@Mail.ru
      [ Script execution time: 0,0257 ]   [ 15 queries used ]   [ Generated: 19.05.24, 00:27 GMT ]