FINSコマンド/フレームを使用してEthernet(UDPパケット)を介してPLCと通信するWPF C#アプリケーションがあります。ソケットでハングアップする例外なしで受信する
READコマンドの実行中にPLCからの応答を取得しようとしたとき、私は成功しWRITE PLCアドレスにコマンドを送信しますが、アプリケーションハング/クラッシュすることができます。
FINSパケットフレームPLCにPCから送信する:次のコード
// 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
};
私のソケットが送受信されています
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-を使用することも試してみましたキャッチ、アプリケーションのハング中に例外がキャッチされません。アプリケーションがに永遠に待っているので、あなたはアプリケーションがハングしている理由は明らかである(screenshot below)
あなたが提案したコードを編集しましたが、問題が残っています。明確にするために:クラッシュは無限ループのためではなく、Receiveメソッドでハングします。私は、ループ内の単純なMessageBoxでそれを確認しました。 – KMC
@KMC - 私が言ったように、実際の応答の長さが256バイトよりも短い場合、receiveへの呼び出しは決して戻りません(タイムアウトヒットまで)。それ以外にも、UDPを使用しているので、受信メッセージが正しいという保証はありません。おそらく、いくつかのバイトが混乱しているか、いくつかのバイトが追加されているか、または何らかのバイトが欠落していることがあります(この場合、予想されるメッセージの長さは決して受信されないため、アプリケーションもハングします)。あなたはこれらの属性を考慮に入れる必要がありますあなたは正しいです – Polity
!コードの長さが問題の原因となり、FINSパケットに固定されたさまざまな問題が発生しました。私は後で私の解決策を掲載します。 – KMC