Hangs on Socket.Receive without exception

I have a WPF C # application that communicates with a PLC (i.e., writes / reads Omron PLC memory addresses) via Ethernet (UDP packets) using the FINS command / frame.

I can successfully send a command to the WRITE address of the PLC, but the application freezes / crashes when trying to get a response from the PLC during the READ command.

FINS frame to send from PC to PLC:

// 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 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 }; 

The following code is my Socket for sending and receiving:

 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; } 

I also tried using Try-Catch , but an exception was not detected during the application freeze. I checked eventvwr which says:

Souce: Application Hangs - "...stopped interacting with Windows and was closed" Detail (screenshot below)

enter image description here

+4
source share
3 answers

The reason you are dependent on the application is obvious, since your application expects to receive data from the source forever. It is good practice to schedule long I / O execution in the background thread or use asynchronous versions of send and receive. Your code contains an error in the following lines:

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

It is expected that totalBytesRcvd will contain the number of expected bytes, and you update it by adding bytesRcvd data. But you never update bytesRcvd. You need to catch the call return value for sock.Receive in bytesRcvd. If this does not solve the problem, it will mean that there are communication problems between the server and the client (note that you use UDP so that it is not unreasonable) or that the actual message is shorter than expected.

+4
source

I had the same problem and found a solution - check socket.Available before trying to get.

 byte[] bytes = new byte[tcpClient.ReceiveBufferSize]; if (socket.Available > 0) { int bytesRec = socket.Receive(bytes); Console.WriteLine("Echoed test = {0}", Encoding.ASCII.GetString(bytes, 0, bytesRec)); } 
0
source

Could you share your final decision? Many thanks.

0
source

Source: https://habr.com/ru/post/1404039/


All Articles