当前位置: 首页 > 知识库问答 >
问题:

c#tcp套接字接收环路中断逻辑

微生俊
2023-03-14

我正在编写一个c#tcp套接字服务器,它将从c套接字应用程序接收数据。现在,除了我的c#接收线程中的循环中断逻辑外,其他一切都正常工作。为了更好地解释,我在下面展示了一段代码片段。

    //creating socket object
    private Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);

    //accepting connections
     TcpListener tcpListener = new TcpListener(ipAdd, iPort);
     tcpListener.Start();
     this.socket = tcpListener.AcceptSocket();
     tcpListener.Stop();        

    //code for 
    //public byte[] ReceiveMessage(ref int intError)
    while (this.socket.Available > 0)
    {
      try
      {
        intBytesReceived = this.socket.Receive(byteReceivedBuffer, byteReceivedBuffer.Length, SocketFlags.None);
        Thread.Sleep(100);
      }
      catch (SocketException ex)
      {
        string str = ex.Message;
        intError = -1;
      }
    }

下面是连续接收数据的线程函数

  //Thread to continuous poll data from client
  //Now this has been done as I need to receive multiple messages from client after server ack received at client side. 

  //Thread quit logic based on manual stop button press
  //I want to have one more logic by which thread will exit if the connection closed by client socket. i.e. a call of 'CloseSocket()' function from c++ application.     

  if (TCPServerListener.serverStatus == TCPServerListener.ServerStatus.Stopped)
  {
    tcpCommunication.Disconnect();
    break;
  }

  while(true)
  {
    int sockError = 0;
    byte[] byteData = tcpCommunication.ReceiveMessage(ref sockError);
    if (byteData.Length > 0)
    {
      ParseBuffer(byteData, ref tcpCommunication);
    }
  }

为了更好地了解情况,我在我的通讯协议下面写了一些东西。

  1. 客户端发起连接。发送数据集
  2. 服务器接收,处理,发送ack
  3. 客户端处于停止模式,直到它收到来自服务器的ack,但没有关闭套接字
  4. 这一次,服务器不会接收任何消息,但是接收线程应该是活动的,因为我正在为每个客户端创建一个线程。
  5. 一旦客户端收到ack,它将继续发送下一个数据
  6. 服务器接收线程现在将获取数据并相应地处理
  7. 一旦客户端关闭其套接字,服务器接收线程也应该关闭

我能够完成我的工作,但服务器-接收器线程没有关闭。这是我的问题。任何建议都会有很大帮助。

共有1个答案

施德运
2023-03-14

根据我的经验,当您使用TCP服务器/客户端套接字关系时,TCP服务器套接字端将位于一个由标志控制的线程中,以继续侦听,直到被告知停止(您的评论中提到了停止按钮)。

客户端运行,直到所有数据都完成,或者控制服务器端的同一个标志被触发。

当客户端连接时,我会将AcceptSocket存储到列表中。当我这样做的时候,我有一个自定义类,它接受AcceptSocket,自定义类有计数器,比如有多少消息或字节被发送/接收到/从这个客户端。

// This should be a threaded method if you're using a button to stop
private void StartTcpListener()
{
    List<ClientClass> clientClassList = new List<ClientClass>();

    TcpListener tcpListener = new TcpListener(ipAdd, iPort);
    tcpListener.Start();

    while (keepListening)
    {
        Socket socket = tcpListener.AcceptSocket();

        // Create a client object and store it in a list
        ClientClass clientClass = new ClientClass(socket);
        clientClassList.Add(clientClass);

        // This method would start a thread to read data from the accept socket while it was connected.
        clientClass.Start();
    }

    foreach (ClientClass client in clientClassList)
    {
        // This method would stop the thread that reads data from the accept socket and close the accept socket
        client.Stop();
    }
    tcpListener.Stop();
}

对于客户端,当从客户端接受套接字读取时,这将是线程控制的,要么线程被中止,要么客户端关闭其端,导致读取返回-1的字节数。

// Threaded method
private void Receive()
{
    // Don't know how much of a buffer you need
    byte[] dataIn = byte[1000];
    while (acceptSocket.Connected)
    {
        // Exception handling so you either end the thread or keep processing data
        try
        {
            int bytesRead = acceptSocket.Read(dataIn);
            if (bytesRead != -1)
            {
                // Process your data
            }
            else
            {
                // -1 Bytes read should indicate the client shutdown on their end
                break;
            }
        }
        catch(SocketException se)
        {
            // You could exit this loop depending on the SocketException
        }
        catch(ThreadAbortException tae)
        {
            // Exit the loop
        }
        catch (Exception e)
        {
            // Handle exception, but keep reading for data
        }
    }

    // You have to check in case the socket was disposed or was never successfully created
    if (acceptSocket != null)
    {
        acceptSocket.Close();
    }
}

// This is the stop method if you press your stop button
private void Stop()
{
    // Aborts your read thread and the socket should be closed in the read thread.  The read thread should have a ThreadState.Stopped if the while loop was gracefully ended and the socket has already been closed
    if (readThread != null && readThread.ThreadState != ThreadState.Stopped)
    {
        readThread.Abort();
    }
}

我想这是我以前做过的基础。我相信现在有“更干净”的方法。这是几年前我用来实现TCP客户机/服务器套接字对象的时候。

希望这能帮助...

 类似资料:
  • 我使用Android应用程序通过TCP套接字与同一局域网上的PC java应用程序进行通信、发送和接收消息。下面是我在android中使用的Asynctask的代码,用于发送消息并从PC接收回复: } 我在onPostExcecute中的祝酒词中显示PC的回复。 Android通过BufferedWriter发送消息,而PC上的java应用程序在BufferedReader中接收消息。 PC在收到

  • 问题内容: 我已经用套接字卡住了4h,我使用的方式是只有一个应用程序作为客户端和服务器,一旦客户端连接, 它将与新客户端一起打开theard,并等待消息。 一旦消息发送到服务器,客户端将收到响应,该部分正在正常工作。 客户专区的一部分: 服务器支持2条消息,第一条是“列表”,发送一条命令是“获取值”。 如果客户端将请求命令“列表”,它将运行以下命令:有一个“服务器/客户端”,它正在发送请求并接收一

  • 现在,我可以通过NAT建立连接,但只能使用连接套接字: 但现在,发送SYN数据包进行连接的两个套接字已经连接。 你会认为我会做的,通过两个NATs得到一个连接,万岁。

  • socket_read和socket_recv之间有什么区别?我正在尝试使用PHP套接字,但使用socket_read时收到了以下警告: 请帮帮我!

  • 我正在开发一个通过TCP/IP承载第三方设备的服务器,并且已经经历了突然的连接中断(设备通过蜂窝连接)。我需要找到一种方法来检测断开,而不必将数据写入设备本身。 我的简化套接字代码如下: 如有任何反馈,将不胜感激。

  • 我有一个很奇怪的问题快把我逼疯了。 我有一个Ruby服务器和一个Flash客户端(动作脚本3)。这是一个多人游戏。 问题是,一切都在完美地工作,然后,突然,一个随机的球员停止接收数据。当服务器因为不活动而关闭连接时,大约20-60秒后,客户端接收到所有缓冲的数据。 null 我不认为这是一个操作系统/网络问题,因为我已经从一个位于西班牙的VPS换到了位于爱尔兰的亚马逊EC2,问题仍然存在。 我觉得