使用TcpListener.AcceptSocket(); 在一个单独的线程导致线程阻塞?

我试图解决这个以及调试,但我在这里松散的结束:(是否有任何替代使用它来检查客户端连接?此代码在控制台应用程序中正常工作所以我猜测线程被封锁了,虽然它可能是我看不到的东西?

public partial class Form1 : Form { Socket s; 

套接字的声明。

 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个线程的控制台应用程序接收的,但是在从同一设备上的同一程序向同一个ip和端口发送数据时,这个Windows窗体应用程序似乎没有发生任何事情。 单独的线程只是保持阻塞状态,Android应用程序无法完成通信以发送数据。

它应该阻止。 来自MSDN :

AcceptSocket是一种阻塞方法,它返回一个可用于发送和接收数据的Socket。 如果要避免阻塞,请使用Pending方法确定传入连接队列中是否有可用的连接请求。

您可以将整个实现转为使用异步版本: 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 } 

我建议你喜欢什么是异步/等待ThreadPool服务器? 用于完全实现异步tcp连接处理程序

它应该阻止。 它永远不会返回null。 (为什么每个人都这样做?就像网上没有人正确使用Accept一样。)

您的问题是,在接受一个连接后,您处理该连接并且不执行任何操作以恢复接受。 标准模式是:

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

确保ProcessAsynchronously立即返回。 启动新Task或使用async / await。

由于您永远不会退出while循环,因此您永远无法发送数据。 将所有处理逻辑移动到ProcessAsynchronously