Open pojiro opened 3 months ago
Hi,
Can you confirm (using wireshark or similar) that you are indeed receiving both payloads in the same tcp message?
I think that the problem is the :packet option of :gen_tcp (currently :raw).
Thanks for your quick reply. Currently the machine is located remote. But I will get it. When I get it, I will capture the log with wireshark and confirm it, then report. Thanks!
I attached the packets log, the_packets.pcapng.zip, that I captured by wireshark.
The issue's log is following, <<0x4, 0x7B>>, <<0x4,0x7C>> corresponds to trans id 1147, 1148.
07:44:03.214 [error] (Elixir.Modbux.Tcp) size = 6, payload_size = 17, msg = <<0x4, 0x7B, 0x0, 0x0, 0x0, 0x6, 0x0, 0x5, 0x0, 0x10, 0x0, 0x0, 0x4, 0x7C, 0x0, 0x0, 0x0, 0x5, 0x0, 0x2, 0x2, 0x0, 0x0>>
07:44:03.215 [error] GenServer #PID<0.1849.0> terminating
** (FunctionClauseError) no function clause matching in Modbux.Response.parse/2
(modbux 0.3.13) lib/helpers/response.ex:64: Modbux.Response.parse({:fc, 0, 16, 0}, nil)
(modbux 0.3.13) lib/tcp/client.ex:330: Modbux.Tcp.Client.handle_info/2
(stdlib 6.0) gen_server.erl:2173: :gen_server.try_handle_info/3
(stdlib 6.0) gen_server.erl:2261: :gen_server.handle_msg/6
(stdlib 6.0) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
Last message: {:tcp, #Port<0.69>, <<4, 123, 0, 0, 0, 6, 0, 5, 0, 16, 0, 0, 4, 124, 0, 0, 0, 5, 0, 2, 2, 0, 0>>}
The following capture show the issue packets,
This response was from :gen_tcp
with active: true
, here
then
finally reached here
https://github.com/valiot/modbux/blob/fead05e0b77e054bdb839a4777f9903999d439a1/lib/tcp/tcp.ex#L34
So I guess that :gen_tcp
reads several packets together at once.
Hi, I create this branch, that expose the packet
argument from :gen_tcp
, this parameter (packet_format
in modbux) accepts 0 | 1 | 2 | 4 | :raw
(default: :raw, :raw == 0), however, it seems that the client and the server must match this parameter (https://stackoverflow.com/questions/43957164/erlang-client-server-example-using-gen-tcp-is-not-receiving-anything), so please give it a try, hope this helps.
Example:
# Starts the Client that will connect to a Server with tcp port: 2000
{:ok, cpid} = Modbux.Tcp.Client.start_link(ip: {127,0,0,1}, tcp_port: 2000, timeout: 2000, packet_format: 1)
# Connect to the Server
Modbux.Tcp.Client.connect(cpid)
# Read 1 coil at 20818 from the device 80
Modbux.Tcp.Client.request(cpid, {:rc, 0x50, 20818, 1})
# Parse the Server response
resp = Modbux.Tcp.Client.confirmation(cpid)
# resp == {:ok, [0]}
Hi, I read the stackoverflow link and the section of the book, Programming Erlang). I also read https://stackoverflow.com/questions/36854060/using-packet-n-in-gen-tcp-and-how-to-receive-data-in-a-c-program
In my understanding, I cannot use the option for this case. Because the target machine, modbus server, doesn't support the header length which :gen_tcp
s {:packet, N}
option add. I think we use this option when we write :gen_tcp
in client and server both with same N
.
Thanks.
@alde103 This is not an immediate issue, so it's enough if you took this as a report that I have found such a case.
Hi, thanks for your modbus library. I found an issue when I use this library. So I report.
What happens
Modbux.Tcp.Client terminates when TCP response contains 2 payloads. Following is the log,
There are two payloads in the response.
<<0x7, 0x8E, 0x0, 0x0, 0x0, 0x5, 0x0, 0x2, 0x2, 0x1, 0x80>>
<<0x7, 0x8F, 0x0, 0x0, 0x0, 0x6, 0x0, 0x5, 0x0, 0x10, 0xFF, 0x0>>
But following code try to handle this response as one payload, so it fails.
https://github.com/valiot/modbux/blob/fead05e0b77e054bdb839a4777f9903999d439a1/lib/tcp/client.ex#L315
If you need any info, let me know. Thank you!