using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
//加入網路連線類別庫
using System.Net;
using System.Net.Sockets;
namespace ServiceRequestData
{
class ConnectDevice
{
public string Value = ""; //向Device要回的資料
public bool TimeOut = false; //是否有TimeOut發生
//與Device連線
public ConnectDevice(string hostip,int port,int func,string startaddress,int length)
{
byte[] senddata = SendModbusCommend(func, startaddress, length); //傳送的資料
byte[] recvdata = SocketConnectCommend(hostip,port,senddata); //傳送後接收回來的資料
Value = RecvModbusCommend(recvdata);
}
//Modbus傳送指令 fuction,StartAddress,Length
//支援func:1,2,3,4
//StartAddress:"0f ff"
//length:wordcount,bitcount
private byte[] SendModbusCommend(int func, string StartAddress, int length)
{
byte[] refnum = new byte[2];
byte[] count = new byte[2];
byte[] Commend = new byte[12];
refnum = strToHexByte(StartAddress);
count = BitConverter.GetBytes(length);
for (int i = 0; i < Commend.Length; i++)
switch (i)
{
case 5:
Commend[i] = Convert.ToByte(6); //封包後面長度
break;
case 6:
Commend[i] = Convert.ToByte(1);
break;
case 7:
Commend[i] = Convert.ToByte(func); //function
break;
case 8:
Commend[i] = refnum[0]; //startaddress
break;
case 9:
Commend[i] = refnum[1];
break;
case 10:
Commend[i] = count[1]; //length
break;
case 11:
Commend[i] = count[0];
break;
default:
Commend[i] = Convert.ToByte(0);
break;
}
return Commend;
}
//Modbus接收指令
//傳回字串型態Bytes
private string RecvModbusCommend(byte[] recvcmd)
{
byte [] data = new byte[recvcmd[8]];
for (int i = 9; i < recvcmd.Length; i++)
data[i-9] = recvcmd[i];
return byteToHexStr(data);
}
//TCP同步傳輸:傳送指令後接收資料
private byte[] SocketConnectCommend(string host, int port, byte[] sendBytes)
{
//int port = Convert.ToInt32("502");
//string host = "192.168.1.204";
IPAddress ip = IPAddress.Parse(host);
IPEndPoint ipe = new IPEndPoint(ip, port);
Socket sk = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
//byte[] sendBytes = strToHexByte("00 00 00 00 00 06 01 05 00 01 00 01 00");
byte[] recvBytes = new byte[256];
try
{
sk.Connect(ipe);
sk.Send(sendBytes, sendBytes.Length, 0);
sk.Receive(recvBytes, recvBytes.Length, 0);
sk.Close();
return recvBytes;
}
catch (ArgumentNullException ex)
{
MessageBox.Show(ex.ToString());
TimeOut = true;
return null;
}
catch (SocketException ex)
{
MessageBox.Show(ex.ToString());
TimeOut = true;
return null;
}
}
//十六進位轉成字串 0x00 0x01 0x0f 0xff "00 01 0f ff"
private static string byteToHexStr(byte[] bytes)
{
string returnStr = "";
if (bytes != null)
{
for (int i = 0; i < bytes.Length; i++)
{
returnStr += bytes[i].ToString("X2") + " ";
}
}
return returnStr;
}
//字串轉成Byte陣列 "00 01 0f ff" 0x00 0x01 0x0f 0xff
private static byte[] strToHexByte(string hexString)
{
hexString = hexString.Replace(" ", "");
if ((hexString.Length % 2) != 0)
hexString += " ";
byte[] returnBytes = new byte[hexString.Length / 2];
for (int i = 0; i < returnBytes.Length; i++)
returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
return returnBytes;
}
}
}