На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
  
> нужна помощь по сокетам
    Здравствуйте, я впервые пишу клиент-серверное приложение. Хочу написать сервер к которому могут быть одновременно подключенны несколько клиентов, сервер рассылает всем клиентам одно и тоже сообщение. Покурил msdn и удалось только написать приложение соединяющие сервер только с одним клиентом.
    Логика Сервера:
    ExpandedWrap disabled
      public class ServerManager
          {
            
              private Socket Server; // создаём сокет для сервера
              private IPHostEntry HostEntry; // информация о хосте
              private IPAddress Address; // предосталяет коллекцию ip-адресов сервера
              private IPEndPoint EndPoint; // точка подключения
       
              public ServerManager()
              {
                  CreateConnectPoint();
                  CreateSocket();
              }
              /// <summary>
              /// Создание точки подключения
              /// </summary>
              public void CreateConnectPoint()
              {
                  // получаем имя компьютера и выводим его
                  string hostName = Dns.GetHostName();
                  Console.WriteLine("Computer name: " + hostName);
       
                  // узнаём имя хоста и выводим его
                  HostEntry = Dns.GetHostEntry(hostName);
                  Console.WriteLine("Host name: " + HostEntry.HostName);
       
                  // выбираем ip-адрес для создания сервера
                  int serverPort;
                  if (HostEntry.AddressList.Length == 1)
                  {
                      Console.WriteLine("Creating server on: " + HostEntry.AddressList[0]);
       
                      Address = HostEntry.AddressList[0];
       
                      Console.Write("Enter the server port: ");
                      serverPort = int.Parse(System.Console.ReadLine());
                  }
                  else
                  {
                      Console.WriteLine("---- ---- ---- ----");
                      Console.WriteLine("IP address list: ");
       
                      // выводим список всех ip-адресов
                      int addressIndex = 0;
                      foreach (IPAddress tmpAdress in HostEntry.AddressList)
                      {
                          Console.WriteLine(addressIndex + ": " + tmpAdress);
                          addressIndex++;
                      }
       
                      // спрашиваем пользователя
                      Console.WriteLine("---- ---- ---- ----");
                      Console.Write("Enter index of adress for creating a server: ");
                      addressIndex = int.Parse(System.Console.ReadLine());
       
                      // говорим, где будем создавать сервер
                      Console.WriteLine("Creating server on: " + HostEntry.AddressList[addressIndex]);
       
                      // получаем адрес, необходимый пользователю
                      Address = HostEntry.AddressList[addressIndex];
       
                      Console.Write("Enter the server port: ");
                      serverPort = int.Parse(System.Console.ReadLine());
                  }
       
                  // создаем конечную точку подключения
                  EndPoint = new IPEndPoint(Address, serverPort);
              }
       
              /// <summary>
              /// Создание Сокета Сервера
              /// </summary>
              public void CreateSocket()
              {
                      try
                      {
       
                          // создаем сокет сервера на текущей машине
                          Server = new Socket(AddressFamily.InterNetwork,
                                  SocketType.Stream, ProtocolType.Tcp);
                          
                          
       
                          Console.WriteLine("Server socket created.");
                      }
                      catch (SocketException error)
                      {
                          // 10061 - порт подключения занят/закрыт
                          if (error.ErrorCode == 10061)
                          {
                              Console.WriteLine("Connection port is closed or busy.");
                              Console.WriteLine("Press any key to exit...");
                              Console.ReadKey();
                          }
                      }
       
                      // прослушивание
                      try
                      {
                          // cвязываем удаленную точку с сокетом
                          Server.Bind(EndPoint);
                          // устанавливаем лимит подключений
                          Server.Listen(10);
                          
       
                          // ждем подключение клиента
                          while (true)
                          {
                              Console.WriteLine("Waiting connection...");
                              
                              Server = Server.Accept();                                              
       
                              if (Server.Connected)
                              {
                                  Console.WriteLine("Connection established.");
                                  Console.ReadKey();
                                  break;                            
                              }
                              
                              
                          }
       
                        
                      }
                      catch
                      {
                          throw new Exception("Connection problem.");
                      }
                      
                      
                  
                  
              }
       
              
       
              // отправка сообщения клиенту
              public void SendMessage()
              {
                  string Message;
       
                  Console.WriteLine("Enter your message:");
                  Message = Console.ReadLine();
       
                  byte[] ByteMsg = Encoding.Unicode.GetBytes(Message);
                  
                    
                  Server.Send(ByteMsg);
       
                  Console.WriteLine("Message sended.");            
       
              }
       
       
          }

    Подскажите что нужно изменить для этого. Читал про потоки, асинхронный ввод-выод...не доходит толком.
    Пока думал сам как это сделать возникло пару ламерский вопросов:Зачем вообще нужен метод Listen если каждый раз метод Accept возвращает последнего подключившегося клиента...и старый объект будет просто затираться...
    На один сокет может быть установлено только одно подключение?
    И если возможно хотелось бы ссылочку на какую-нибудь развернутую инфу по сокетам вообще.
    Пожалуйста, давайте развернутый ответ, это тема для меня новая и я, к сожалению, пока далеко не всегда понимаю с полуслова....
    Заранее благодарен.
    Сообщение отредактировано: Nuts -
      Вот примерчик:
      ExpandedWrap disabled
        public static class SomeServer
            {
                public static int port=13000;
         
                public static void Start()
                {            
                    Thread th = new Thread(AcceptThread);
                    th.IsBackground = true;
                    th.Start();
                }
         
                static void AcceptThread()
                {                  
                    
        //создаём и запускаем TcpListener
                        IPAddress localAddr = IPAddress.Parse("127.0.0.1");
                        TcpListener server = new TcpListener(localAddr, port);
                        server.Start();              
                        
        //принимаем клиентов
                        while (true)
                        {
                            //приняли клиента                
                            TcpClient client = server.AcceptTcpClient();      
                            //запустили поток, работающий с этим клиентом
                            Thread th = new Thread(new ParameterizedThreadStart(ClientThread));
                            th.IsBackground = true;
                            th.Start(client as object);                    
                            
                            //пошли принимать клиентов дальше
                        }                
                }
         
                static void ClientThread(object o)
                {
                    //клиент, с которым работает этот поток
                    TcpClient client = o as TcpClient;
                    //создаём поток обмена данными с клиентом
                    NetworkStream stream = client.GetStream();
                    StreamReader reader = new StreamReader(stream, Encoding.BigEndianUnicode);
                    StreamWriter writer = new StreamWriter(stream, Encoding.BigEndianUnicode);
                    writer.AutoFlush = true;
         
                    //читаем строки из потока, т.е. от клиента, и выводми
                    while (true)
                    {
                         string str = reader.ReadLine();
                         MessageBox.Show(str);
                    }
         
         
                }
            }


      Примерно так. Писал прямо здесь, только для иллюстрации, поэтому могут быть ошибки.
      Сообщение отредактировано: IL_Agent -
      1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
      0 пользователей:


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