c# - 毫无异常(exception)地卡在 Socket.Receive 上

标签 c# sockets udp plc fins

我有 WPF C# 应用程序,它使用 FINS 命令/帧通过以太网(UDP 数据包)与 PLC 通信(即写入/读取 Omron PLC 的内存地址)。

我可以成功地向 WRITE PLC 地址发送命令,但是当在 READ 命令期间尝试从 PLC 获得响应时,应用程序挂起/崩溃。

PC发送给PLC的FINS包帧:

// Packets send to PLC to read Memory Address DM1000
byte[] sendPacket = new byte[]
{
    // 81 00 02 00 00 00 00 FF 00 19 01 01 82 00 64 00 00 01

    // FINS header
    0x81, //0.(ICF) Display frame information: 1000 0001 (Response required)
    0x00, //1.(RSV) Reserved by system: (hex)00
    0x02, //2.(GCT) Permissible number of gateways: (hex)02
    0x00, //3.(DNA) Destination network address: (hex)00, local network
    0x00, //4.(DA1) Destination node address: (hex)00, local PLC unit
    0x00, //5.(DA2) Destination unit address: (hex)00, PLC
    0x00, //6.(SNA) Source network address: (hex)00, local network
    0xFE, //7.(SA1) Source node address: (hex)05, PC's IP is 100.0.0.254
    0x00, //8.(SA2) Source unit address: (hex)00, PC only has one ethernet
    0x19, //9.(SID) Service ID: just give a random number 19

    // FINS command
    0x01, //10.(MRC) Main request code: 01, memory area read
    0x01, //11.(SRC) Sub-request code: 01, memory area read

    // Memory Area
    0x82, //12.Memory area code (1 byte): 82(DM)

    // Address information
    0x00, //13.Read start address (2 bytes): D100
    0x64, 
    0x00, //15.Bit address (1 byte): Default 0

    // Words read
    0x00, //16. Words read (2bytes)
    0x01
};

以下代码是我的Socket收发:

sock = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
sock.Connect(SERV_IP_ADDR, FINS_UDP_PORT);
sock.Send(sendPacket, 0, sendPacket.Length, SocketFlags.None);

int totalBytesRcvd = 0;     // Total bytes received so far
int bytesRcvd = 0;          // Bytes received in last read
while (totalBytesRcvd < sendPacket.Length)
{
    bytesRcvd = sock.Receive(sendPacket, totalBytesRcvd, sendPacket.Length - totalBytesRcvd, SocketFlags.None);
    if (bytesRcvd == 0)
    {
        MessageBox.Show("Connection closed prematurely.");
        break;
    }

    totalBytesRcvd += bytesRcvd;
}

我也尝试过使用 Try-Catch,但在应用程序挂起期间没有捕获到异常。我检查了 eventvwr,它说:

来源: 应用程序挂起 - “...停止与 Windows 交互并已关闭” 详细信息:(下面的截图)

enter image description here

最佳答案

您的应用程序挂起的原因显然是因为您的应用程序一直在等待从源中获取数据。在后台线程上安排长时间运行的 IO 或使用发送和接收的异步版本是一种很好的做法。您的代码包含以下行的错误:

while (totalBytesRcvd < msg.Length) 
{ 
    // Application hangs right at the sock.Receive 
    sock.Receive(msg, totalBytesRcvd, msg.Length - totalBytesRcvd, SocketFlags.None); 

    totalBytesRcvd += bytesRcvd; 
} 

您正在等待 totalBytesRcvd 包含预期的字节数,并且您正在通过添加 bytesRcvd 数据来更新它。但是您永远不会更新 bytesRcvd。您需要在 bytesRcvd 中捕获对 sock.Receive 的调用的返回值。如果这不能解决问题,则意味着服务器和客户端之间存在通信问题(请注意,您使用的是 UDP,因此这可能不是不合理的)- 或者实际消息的长度比预期。

关于c# - 毫无异常(exception)地卡在 Socket.Receive 上,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9918628/

相关文章:

sockets - UDP 数据包可以像 TCP 一样部分发送吗?

TCP IP : Is it possible to read what TCP/UDP data a program is sending remotely?

Python UDP广播

c# - 我怎样才能将我的数组属性包含到类构造函数中并能够通过对象初始化访问它?

c# - Mono 服务异常 - 身份验证或解密失败

c# - ThreadLocal 并等待

Java socket IOException - 权限被拒绝

c# - 复制一个 mongodb 集合

python - 我的python客户端向c服务器发送一个整数,但服务器收到0

java - 无法启动套接字服务器java