2016-10-05 13 views
0

Мои клиент-серверные программы хорошо работают друг с другом, но только при запуске и запуске сервера до запуска моего клиента. Если клиент не может подключиться с первой попытки, я не могу заставить его попробовать еще раз.Использование UdpClient, как вы пытаетесь выполнить попытку UdpClient.Connect() до тех пор, пока это не удастся?

Вот мой метод connect моего клиента.

public void connect() 
    {   
     IPAddress server_address = IPAddress.Parse("127.0.0.1"); 
     IPEndPoint server_ip = new IPEndPoint(server_address, 5685); 
     Console.WriteLine("2"); 
     bool connected = false; 
     while (!connected) 
     { 
      try 
      { 
       Console.WriteLine("IN CONNECTED"); 
       udp_client.Connect(server_ip); 
       byte[] send_data = Encoding.ASCII.GetBytes("INIT"); 
       udp_client.Send(send_data, send_data.Length); 
       byte[] received_bytes = udp_client.Receive(ref server_ip); 
       string received_data = Encoding.ASCII.GetString(received_bytes); 
       if (received_data == "INIT") 
       { 
        connected = true; 
        Console.WriteLine("RECEIVED INIT"); 
        listen(server_ip); 
       } 

      } 

      catch (Exception e) 
      { 
       Console.WriteLine(e); 
      } 
     } 
    } 

То, что я надеялся увидеть это udp_client.Connect(server_ip) в цикле, пока я не получил, что сообщение «INIT» с сервера.

Как и в настоящее время, нет петли. Кажется, что он застрял на udp_client.Receive(ref server_ip).

Любая помощь будет оценена!

+0

Это выглядит как петля для меня - не выход из строя, если только connected = true. Что происходит? Отладка и выясните, почему соединение установлено на true. –

+0

Я пытаюсь сказать, что цикла не происходит. Он либо подключается, либо нет, и программа должна быть перезапущена. При отладке цикл зависает на 'udp_client.Receive()'. – MrDysprosium

+0

Затем получите блокирующий вызов, и он будет ждать вечно, пока он не получит что-то. Это не повесить. Поместите метод в отдельный поток, и он просто подождёт, пока не получит ответ, а затем продолжит. –

ответ

1

Это pseudoCode - вам нужно будет перемещать somethings в область класса, чтобы позволить будущим send/receive (что вы бы сделали, используя другой метод). Это только разработан, чтобы показать вам, как подключиться, когда блоки подключения:

bool isClientConnected = false; 
var connector = new System.ComponentModel.BackgroundWorker(); 

public void connectToUDP(){ 
    connector.DoWork+= connect; 
    connector.RunWorkerAsync(); 
} 

private void connect(object sender, DoWorkEventArgs e) 
{   
    IPAddress server_address = IPAddress.Parse("127.0.0.1"); 
    IPEndPoint server_ip = new IPEndPoint(server_address, 5685); 
    Console.WriteLine("2"); 

       try 
     { 
      Console.WriteLine("Waiting for server..."); 
      udp_client.Connect(server_ip); 
      byte[] send_data = Encoding.ASCII.GetBytes("INIT"); 
      udp_client.Send(send_data, send_data.Length); 
      byte[] received_bytes = udp_client.Receive(ref server_ip); 
      string received_data = Encoding.ASCII.GetString(received_bytes); 
      if (received_data == "INIT") 
      { 
       isClietConnected = true; 
       Console.WriteLine("now connected"); 
       listen(server_ip); 
      } 


     catch (Exception e) 
     { 
      Console.WriteLine(e); 
     } 

} 
public bool sendReceiveUDP(string send){ 
    if(!isClientConnected){ 
      return false; 
    } 
    //perform send 
    return true; 
} 

Вы бы затем поддерживать подключенную сессию, используя класс сферы и отправки/приема с использованием другого метода. Это для подключения только потому, что вам нужно сделать это только один раз.

Как установить что-то вроде этого: до

private bool isConnected = false(); 
    private bool send(){ 
     if(!isConnected){ 
      connect(); 
     } 
     //send 
    } 
    private bool connect(){ 
     if(!isConnected){ 
      //launch connection thread 
     } 
    } 
    private delegate void onNewReceive(string message); 
    public event onNewReceive onNewReceiveEvent; 
    public void fireEvent(string message){ 
     onNewReceiveEvent.Invoke(message); 
    } 
     private void waitForData(object sender, DoWorkEventArgs e){ 
    //this is the backgroundworker 
    while(true){ 
    receive(); 
    fireEvent(message); 
    } 
    } 

Затем, подписываться на onNewREceivedEvent в другом классе и обрабатывать входящие сообщения. onNewReceivedEvent + = processInboundMEsasage();

Это все psuedocode и «мозг скомпилирован» (creit для других), поэтому он предназначен только для демонстраций. Без intellisense я потерян.

+0

Мне не хватает, как это происходит ...? – MrDysprosium

+0

Вам не нужно зацикливаться. Прием будет блокироваться, пока он не получит что-то. Если вы хотите ОТПРАВИТЬ что-то в цикле, вам нужно сделать это другим способом. Как только вы вызываете receive(), поток останавливается (блокируется), пока не получит что-то. Он будет ждать вечно. Вот почему он должен быть в другом потоке. Как только он завершает свой долг (получает что-то), поток будет продолжать движение после приема(), как если бы это была только микросекунда, даже если она была четыре часа –