三菱PLCの「手順あり」とかいうクソに対応した
お疲れ様です。三菱PLCのソケット通信で「手順あり」「Keep-Alive使用」とかいう特級のクソにぶち当たったので、備忘録的にPythonでの実装をメモしておきます。
import socket
#PLCだと送受のポートが分かれてることがあるのでこんな感じになる
ip = "192.168.3.39"#IP,ポートなどは適当
port = 10000
port1 = 10001
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s1 = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET,socket.SO_KEEPALIVE,1)#KEEP ALIVEを有効化
s1.setsockopt(socket.SOL_SOCKET,socket.SO_KEEPALIVE,1)#KEEP ALIVEを有効化
s.connect((ip, port))
s1.connect((ip, port1))
print("Connected")
#無限ループでまちうけ
#今回は 受信待機→受信→サブヘッダ応答→受信データに対して64byteのデータで返信 を想定
while True:
receive = s.recv(4096)
data1_1=bytearray(bytes(receive))
print(data1_1)
if receive != b"" and data1_1[0] == 0x60:#無限ループにするとウンコpythonが受信待機してくれなくなって無限にprintしやがるので回避。あとPLCとかいう汚物も手順ありでゴミを送ってくるので回避
data2_1=bytearray([0xe0,0x00]) #サブヘッダ返答 これが無いと手順あり通信がうまくいかない くたばれ三菱
s.sendall(data2_1)
print(data2_1)
data3_1=bytearray([0]*132)#64バイトのデータ+手順有に必要なゴミどもの送受を想定
#print(data3_1)
if data1_1[4]==0x31 and data1_1[5]==0x34:
data3_1[0]=0x60#ヘッダ 手順ありだと必須
data3_1[1]=0x00#ヘッダ 手順ありだと必須
data3_1[2]=0x40#データ長
data3_1[3]=0x00#データ長※データ長はデータ長までの部分を除いてフッタまでを含めた大きさ この場合10進数で64(byte)の意味。これも手順有では必須
#あとはbytearrayで作った配列に送受したいデータをぶち込んでどうぞ
s1.sendall(data3_1)
print(data3_1)
s.close()
print("END")
サブヘッダとかヘッダってやつが難解で、三菱のマニュアルにちょこーーーーーーーーーーーーーーーーとしか書いてないんですよね。絶対PLCのLANカード買わせるためにあんな書き方したでしょ。