2014-07-23 5 views
4

Я делаю простой проект с участием одной серверной программы и одной клиентской программы. Он должен проверить, подключен ли клиент (со стороны сервера) и наоборот для клиента.Как вы можете повторно использовать или подключаться к сокету на том же порту после отключения?

Когда клиент теряет интернет, сервер должен знать, что он отключен. Затем клиент должен подключиться к серверу, когда он восстановит Интернет.

Когда клиент теряет интернет, а затем восстанавливает интернет, я не могу повторно подключиться с использованием того же порта.

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

Я видел, что он может быть застрял на некотором TIME_WAIT свойстве, установленном ОС в реестре (в случае Windows). Мой вопрос, чтобы повторить, заключается в том, чтобы иметь возможность использовать один и тот же сокет (что более важно, тот же самый порт) для повторного подключения после того, как клиент потерял и восстановил Интернет, и все еще слушал, ожидая повторного подключения.

Как я уже сказал, я могу обнаружить, когда он отсоединяется со стороны сервера, а также от клиента, но когда я пытаюсь подключиться к нему с использованием того же порта и с тем же сокетом или перезапустимым сокетом, он все равно не будет подключаться и он вообще не появится. Есть ли какое-либо предложение помочь решить эту проблему? Я долго искал эту проблему.

Сценарий:

  1. сервер прослушивает
  2. клиент подключается к серверу
  3. Отключайте Клиент из интернет
  4. подключи Клиент интернет кабель обратно в
  5. Client автоматически подключится к серверу (в настоящее время Безразлично» t сделать это на одном и том же порту)

TL; DR Потерян и восстановлен интернет на модели клиент-сервер, но он не может использовать один и тот же сокет и порт для подключения к серверу.

КОД:

private void button2_Click(object sender, EventArgs e) 
    { 

     // This will stop the threads/connections and toggle the button back to its original state 
     if (button2.Text == "Stop Listening") 
     { 

      listener.Close(); 
      stop = true; 
      threadsActive = false; 
      button2.Text = "Start Listening"; 
      textBox1.AppendText("Manually Closed Threads/Connections" + Environment.NewLine); 

     } 
     else 
     { 

      listenThread = new Thread(listenLoop); 
      listenThread.IsBackground = true; 
      status = new Thread(checkIfOnline); 
      status.IsBackground = true; 
      stop = false; 
      threadsActive = true; 
      button2.Text = "Stop Listening"; 
      localEndPoint = new IPEndPoint(IPAddress.Parse("129.59.79.65"), 3000); 
      listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
      listenThread.Start(); 
      status.Start(); 

     } 

    } 

===================================== ===============

private void listenLoop() 
    { 

     try 
     { 

      listener.Bind(localEndPoint); 
      listener.Listen(100); 

      textBox1.AppendText("Waiting for a client..." + Environment.NewLine); 

      listener = listener.Accept(); 
      textBox1.AppendText("Client Connected!!" + Environment.NewLine); 

      status.Start(); 

      while (!close) 
      { 

       if (stop) 
        return; 
       // server connection loop 

      } 

      if(close) 
       return; 

     } 
     catch (Exception excp) 
     { 



     } 

    } 

============================ ========================

private void ResetSocket() 
    { 

     // stop all threads and connections 
     stop = true; 
     listener.Close(); 

     textBox1.AppendText("Attempting to kill threads..." + Environment.NewLine); 
     //while (listenThread.IsAlive == true || status.IsAlive == true) { /*loop until the threads are killed*/ textBox1.AppendText("Closing Threads..."); } 
     //listener.Close(); 
     threadsActive = false; 

     textBox1.AppendText("All Threads/Connections Closed" + Environment.NewLine + "Restarting Threads/Connections..." + Environment.NewLine); 

     // re-establish and start threads and connections again 
     stop = false; 
     listenThread = new Thread(listenLoop); 
     listenThread.IsBackground = true; 
     status = new Thread(checkIfOnline); 
     status.IsBackground = true; 
     threadsActive = true; 
     localEndPoint = new IPEndPoint(IPAddress.Parse("129.59.79.65"), 3000); 
     listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 
     listenThread.Start(); 
     status.Start(); 

     textBox1.AppendText("Threads/Connections Restarted Successfully" + Environment.NewLine); 

    } 
+0

Не могли бы вы предоставить какой-то код о том, как вы слушаете порт? Обычно вы слушаете порт и создаете новый сокет всякий раз, когда клиент подключается –

+0

, вы читаете документацию здесь: http://msdn.microsoft.com/en-us/library/fx6588te(v=vs.110).aspx Этот код позволит вам правильно обрабатывать переподключения –

+0

Определить «невозможно подключиться к одному порту». Что происходит вместо этого? – EJP

ответ

2

не связывайте сокет клиента. Важен только порт сервера.

На стороне сервера просто слушайте прослушивание гнезда. Когда слуховой сокет принимает соединение, он возвращает новый сокет, который представляет это соединение. Когда вы обнаружите потерю соединения, закройте соответствующий разъем для подключения, но оставите рабочую розетку.

На стороне примечания, IMO - лучший способ обнаружить потерю соединения - это периодически отправлять данные (в обоих направлениях).

У меня есть TCP/IP .NET FAQ в моем блоге. Это .NET, но общие концепции применимы к любому сценарию TCP/IP.

+0

Я сделал то, что вы сказали, и это, казалось, сработало. Исправленные функции размещены в этой ссылке для удаления (могут быть другие проблемы, связанные с другими темами, помимо тех, которые упомянуты в этом вопросе, но части, в которых я нуждался, исправлены): https://dl.dropboxusercontent.com/u/ 12438255/simple_server/functions.zip – Zach

0

Чтобы подробно рассказать о потрясающем ответе Стивена Клири. После того, как мы создадим и привяжем его, сервер начнет прослушивать. Управление вводит бесконечный цикл. Клиент подключается к серверу. Если теперь отключить Интернет, клиент выдает исключение, которое возвращает нас к вершине бесконечного цикла, где мы ожидаем подключения к сети, прежде чем пытаться принять другое соединение.

private void ListenForIncomingHttpRequests() 
{ 
    AwaitNetworkAvailability(); 

    // create 
    var serverSocket = 
     new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp); 

    // bind 
    var localEndpoint = new IPEndPoint(IPAddress.Any, port: 12000); 
    serverSocket.Bind(localEndpoint); 

    // listen 
    serverSocket.Listen(backlog: 25); 

    while (true) 
    { 
     AwaitNetworkAvailability(); 

     try 
     { 
      // client connects to the server 
      using (var clientSocket = serverSocket.Accept()) 
      { 
       ProcessServerSocketRequest(clientSocket); 
      } 
     } 
     catch (Exception ex) 
     { 
      _logger.Write(ex.ToString()); 
     } 
    } 
} 
Смежные вопросы