2014-07-10 43 views
2

我试图解决这个问题,以及调试,但我闲着这里:(没有任何替代使用此检查客户端连接?此代码工作正常在一个控制台应用程序,所以我猜线程被阻塞,尽管它可能是别的东西,我不能看?使用TcpListener.AcceptSocket();在一个单独的线程导致线程阻塞?

插座的
public partial class Form1 : Form 
{ 
    Socket s; 

Declatation。

private void startButton_Click(object sender, EventArgs e) 
    { 
     checkTimer.Enabled = true; 
     if (bw.IsBusy != true) 
     { 
      bw.RunWorkerAsync(); 
     } 
    } 

后台线程启动按钮按下。

private void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
     BackgroundWorker worker = sender as BackgroundWorker; 

     working(); 
} 

线程运行“工作”方法。

private void working() 
{ 
    if (threadFirstRun == true) 
    { 
      threadFirstRun = false; 
    } 

     try 
     { 

      String tempAddr = tbAddr.Text; 
      IPAddress ipAd = IPAddress.Parse("147.197.204.172"); 
      // use local m/c IP address, and 
      // use the same in the client 
      String tempPort = tbPort.Text; 
      /* Initializes the Listener */ 
      TcpListener myList = new TcpListener(ipAd, 3000); 

      /* Start Listeneting at the specified port */ 
      myList.Start(); 
      tcConnection1 = "Console:\n" + "The server is running at port 3000..."; 
      tcConnection2 = "\n" + "The local End point is :" + myList.LocalEndpoint; 
      tcConnection3 = "\n" + "Waiting for a connection....."; 

      while (true) 
      { 
       s = myList.AcceptSocket(); 
       if (s != null) 
       { 
        if (connectionEstab == false) 
        { 
         tcEstab = "\n" + "Connection accepted from " + s.RemoteEndPoint; 
         connectionEstab = true; 
        } 


        byte[] b = new byte[100]; 
        int k = s.Receive(b); 
        //Console.WriteLine("Recieved..."); 
        for (int i = 0; i < k; i++) 
        { 
         //Console.Write(Convert.ToChar(b[i])); 
         tcValue = tcValue + Convert.ToString(b[i]); 
         valueArray[ii] = (float)Convert.ToDouble(b[i]); 
        } 
        tcValue = tcValue + "\n"; 
        ii++; 
       } 
       else 
       { 
        Thread.Sleep(200); 
       } 
      } 

      ASCIIEncoding asen = new ASCIIEncoding(); 
      s.Send(asen.GetBytes("The string was recieved by the server.")); 
      rtbConsole.Text = rtbConsole.Text + "\n" + "Sent Acknowledgement"; 
      /* clean up */ 
      s.Close(); 
      myList.Stop(); 
     } 
     catch (Exception ex) 
     { 
      tcError = "\n\n" + "Error..... " + ex.StackTrace; 
     } 
} 

工作方法在调用时myList.AcceptSocket启动服务器和块();?

private void bw_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) 
{ 
     if ((e.Cancelled == true)) 
     { 
      rtbConsole.Text = rtbConsole.Text + "\n" + "Canceled!"; 
     } 

     else if (!(e.Error == null)) 
     { 
      rtbConsole.Text = rtbConsole.Text + "\n\n" + ("Error: " + e.Error.Message); 
     } 

     else 
     { 
      rtbConsole.Text = rtbConsole.Text + "\n" + "Done!"; 
     } 
} 

private void bw_ProgressChanged(object sender, ProgressChangedEventArgs e) 
{ 
     rtbConsole.Text = rtbConsole.Text + "\n" + (e.ProgressPercentage.ToString() + "%"); 
} 

private void stopButton_Click(object sender, EventArgs e) 
{ 
     checkTimer.Enabled = false; 
     if (bw.WorkerSupportsCancellation == true) 
     { 
      bw.CancelAsync(); 
     } 
} 

一些完整性的其他方法。

编辑为我吮吸解释我的问题:(

从我的Android设备发送的数据是通过运行1个线程控制台应用程序收到,但似乎没有任何在发送数据到这个Windows窗体应用程序发生。在同一设备上相同的IP和端口从同一程序的独立线程只是停留阻塞和Android应用程序无法完成通信发送的数据

+0

http://msdn.microsoft.com/en-us/library/system.net.sockets.tcplistener.acceptsocket(v=vs.110).aspx另请参阅http://msdn.microsoft.com/zh-cn/ -us/library/system.net.sockets.tcplistener.acceptsocketasync(v = vs.110).aspx – Tyler

+0

它应该阻止。整个while循环检查'Pending'是一个不好的方法。另外,如果你简单地用'await'来使用异步方法,这将会容易得多。 – Luaan

+0

编辑工作方法删除挂起检查,反正没有在控制台应用程序。在我查看之前,没有看到“等待”。 – sp10acnFIFO

回答

1

它应该阻止MSDN:。

AcceptSocket是返回一个Socket,你可以使用 发送和接收数据的阻塞方法。如果你想避免阻塞,使用 挂起的方法来确定连接请求是在 传入连接队列中可用。

您可以将您的整个实施变为使用异步版本:AcceptSocketAsync。请注意,此操作不会阻止您的方法,它会将控制权返回给主叫方,直至连接了新的Socket

private async void bw_DoWork(object sender, DoWorkEventArgs e) 
{ 
    BackgroundWorker worker = sender as BackgroundWorker; 
    await WorkingAsync(); 
} 

而且里面WorkingAsync

private Task WorkingAsync 
{ 
    // Do all other stuff, 

    Socket socket = await myList.AcceptSocketAsync(); 

    // Do rest of stuff with the socket 
} 

,我建议你在What is the async/await equivalent of a ThreadPool server?喜欢完全实现它应该阻止一个异步的TCP连接处理器

+0

这有同样的问题,程序不会继续,直到套接字可用。 – usr

+0

如果没有收到套接字,继续他的逻辑没有意义。它或者这个或者'while(true)'阻止,我认为这个版本更可取 –

+0

好吧,我的评论没有意义。不知道我为什么这么说。无论如何,这个答案并不能解决他的问题。 – usr

2

的。它永远不会返回null。 (为什么大家都这样做呢?这就像没有人在网络上使用正确接受。)

你的问题是,接受一个连接之后,你处理这方面,什么也不做恢复接受。标准模式是:

while (true) { 
var connectionSocket = listeningSocket.Accept(); 
ProcessAsynchronously(connectionSocket); 
} 

确保ProcessAsynchronously立即返回。开始一个新的Task或使用异步/等待。

因为你永远不会退出while循环,所以你永远不会发送数据。将所有处理逻辑移至ProcessAsynchronously