C++(MFC)とPLCはTCP通信を用いる
45628 ワード
最近やっているプロジェクトは、MFCがserverとして、PLCがclientとして、2日間やったが、やはり基礎が悪いので、まず出会った問題を記録しておきましょう.TCP、UDPテストソフト:https://download.csdn.net/download/qq_38109843/11255416あ、通信が正常かどうかをテストできます.自分で書いた通信はテストソフトと同じように、受信PLC側に「?」と表示され、PLCが送るのはcharタイプではなく、バイナリ、16進数かもしれないし、混合しているかもしれない(プロトコル書にはint、char、realなどのタイプがある).最後に16進数でしか受信できないことが分かったが、長さはまだ異なるので、観察して調整したが、具体的な手順は以下の通りである.
プログラム
宣言スレッド:
スレッドの定義:
16進数からintタイプへの変換:10進数から16進数への変換char:10進数からASCII 16進数への変換real:実はIEEE 756標準32ビット浮動小数点型演算で、最初は16進数からunsigned intへの変換を準備して、それから2進数に変換して、それから10進数に変換して、それから復号して最後に得て、コードはここにあります:http://www.bccn.net/paste/1695/ああ、本当に煩わしいのはだめで、入力はまだunsigned intで、まだ16進数をunsigned intに変えて、煩わしいのは比べて、最後にこの方法を放棄します.
最後の二言三言で終わり、ネットでいろいろ調べて、やっと模索しました.変換コード
プログラム
宣言スレッド:
CWinThread *thread_recv;
static UINT server_thd(void *param);
スレッドの定義:
thread_recv = AfxBeginThread(server_thd, this, THREAD_PRIORITY_NORMAL, 0, 0, NULL);
UINT CGigeCameraDemoDlg::server_thd(void *param)
{
CString Coil_number;
CString Materia_width;
CString Lead_postion;
CString Running_Speed;
CString Telegram_designation;
CString Telegram_counter;
CString Telegram_length;
WSADATA wsaData;
WORD wVersion;
wVersion = MAKEWORD(2, 2);
WSAStartup(wVersion, &wsaData);
SOCKADDR_IN local_addr;
SOCKADDR_IN client_addr;
int iaddrSize = sizeof(SOCKADDR_IN);
int res;
char msg[1024];
CGigeCameraDemoDlg * dlg = (CGigeCameraDemoDlg *)AfxGetApp()->GetMainWnd();
local_addr.sin_family = AF_INET;
local_addr.sin_port = htons(28357);
local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
if ((listen_sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{
dlg->update(" ");
}
if (bind(listen_sock, (struct sockaddr*) &local_addr, sizeof(SOCKADDR_IN)))
{
dlg->update(" ");
}
listen(listen_sock, 1);
if ((sock = accept(listen_sock, (struct sockaddr *)&client_addr, &iaddrSize)) == INVALID_SOCKET)
{
dlg->update("accept ");
}
else
{
CString port;
port.Format(_T("%d"), int(ntohs(client_addr.sin_port)));
dlg->update(" :" + CString(inet_ntoa(client_addr.sin_addr)) + " :" +
port);
}
while (1)
{
if ((res = recv(sock, msg, 1024, 0)) == -1)
{
dlg->update(" ");
break;
}
else
{
//msg[res] = '\0';
CString msg1;
CString msg_all;
for (int i = 0; i < res; i++)
{
msg1.Format(_T("%X"), msg[i]); // 16
int length = msg1.GetLength();
if (length > 2)
{
msg1 = msg1.Right(2);
}
else
{
if (length < 2) {
msg1 = "0" + msg1;
}
}
msg_all += msg1;
}
//dlg->update(msg_all);
Telegram_designation = msg_all.Mid(0, 8);
Telegram_counter = msg_all.Mid(8, 8);
Telegram_length = msg_all.Mid(16, 8);
Coil_number = msg_all.Mid(24, 24);
Materia_width = msg_all.Mid(48, 8);
Lead_postion = msg_all.Mid(56, 8);
Running_Speed = msg_all.Mid(64, 8);
dlg->update(" :" + Coil_number + " :" + Materia_width + " :" + Lead_postion + " :" + Running_Speed);
int td = HEXTOTEN(Telegram_designation);
int tc = HEXTOTEN(Telegram_counter);
int tl = HEXTOTEN(Telegram_length);
//std::cout << td << " " << tc << " " << tl << " ";
CString coil_all="";
for (int i = 0;i < 12; i++)
{
CString tmp = Coil_number.Mid(2*i, 2);
int cn = HEXTOTEN(tmp);
CString cn1;
cn1.Format(_T("%c"), cn);//
coil_all.Format(_T("%s%s"), coil_all, cn1);
//std::wcout << "coil_all" << coil_all.GetBuffer() << " ";
}
dlg->m_value1.SetWindowText(coil_all);
coil_number = coil_all;
USES_CONVERSION;
int mw = HEXTOTEN(Materia_width);
int lp = HEXTOTEN(Lead_postion);
int rs = HEXTOTEN(Running_Speed);
int a = 1557;
CString s;
s.Format(_T("%d"), mw);
dlg->m_value3.SetWindowText(s);
//int a =0x43160000;
//float b = *(float*)&a;
//printf("%f
",b);
int n = strtol(T2A(Materia_width), NULL, 16);
float b = *(float*)&n;
}
}
return 0;
}
16進数からintタイプへの変換:10進数から16進数への変換char:10進数からASCII 16進数への変換real:実はIEEE 756標準32ビット浮動小数点型演算で、最初は16進数からunsigned intへの変換を準備して、それから2進数に変換して、それから10進数に変換して、それから復号して最後に得て、コードはここにあります:http://www.bccn.net/paste/1695/ああ、本当に煩わしいのはだめで、入力はまだunsigned intで、まだ16進数をunsigned intに変えて、煩わしいのは比べて、最後にこの方法を放棄します.
最後の二言三言で終わり、ネットでいろいろ調べて、やっと模索しました.変換コード
vector<bool> get_hex_2b(unsigned int a);
int get_hex_jiema(vector<bool> a);
float get_10dec(vector<bool> a);
int HEXTOTEN(CString s);
vector<bool> get_hex_2b(unsigned int a)//
{
vector<bool> x;
for (int i = 0; i < 32; i++)
{
if ((((int)a)&(0x80000000 >> i)))
{
x.push_back(1);
}
else
{
x.push_back(0);
}
}
/
//cout << " :" << endl;
//for_each(x.begin(), x.end(), fun);
//cout << endl;
///
return x;
}
int get_hex_jiema(vector<bool> a)//
{
// 1-8
vector<bool> yima(a.begin() + 1, a.begin() + 9);
vector<bool>::iterator ite = yima.begin();//
unsigned int sum = 0;
//
for (int i = 0; i < 8; i++)
{
sum = sum + (*ite)*pow(2, 7 - i);
ite++;
}
int jiema = sum - 127;
return jiema;
}
float get_10dec(vector<bool> a)//
{
// , 1,
vector<bool> zhengshu(1, 1);
vector<bool> xiaoshu;//
// 9-
vector<bool> weima(a.begin() + 9, a.end());
// , ,
zhengshu.insert(zhengshu.end(), weima.begin(), weima.begin() + get_hex_jiema(a));
//
xiaoshu.insert(xiaoshu.end(), weima.begin() + get_hex_jiema(a), weima.end());
//
//
//cout << " :" << endl;
//for_each(zhengshu.begin(), zhengshu.end(), fun);
//cout << endl;
//cout << " :" << endl;
//for_each(xiaoshu.begin(), xiaoshu.end(), fun);
//cout << endl;
/
float zheng_shu = 0;
float xiao_shu = 0;
float sum = 0;
//
for (int i = zhengshu.size(); i > 0; i--)
{
zheng_shu = zheng_shu + zhengshu[i - 1] * pow(2, zhengshu.size() - i);
}
//
for (int i = 0; i < xiaoshu.size(); i++)
{
xiao_shu = xiao_shu + xiaoshu[i] * pow(2, -(i + 1));
}
sum = zheng_shu + xiao_shu;
//
if (a[0] == 1)
sum = 0 - sum;
return sum;
}
int HEXTOTEN(CString s)
{
USES_CONVERSION;
//LPWSTR ss1 = T2A(s);
int i = 0, sum;
string sz2 = T2CA((LPCTSTR)s);
//string sz2 =s.GetBuffer();
int count123 = sz2.length();
sum = 0;
for (i = count123 - 1; i >= 0; i--)// ,
{
if (sz2[i] >= '0'&&sz2[i] <= '9')//
{
sum += (sz2[i] - 48)*pow(16, count123 - i - 1);
}
else if (sz2[i] >= 'A'&&sz2[i] <= 'F')//
{
sum += (sz2[i] - 55)*pow(16, count123 - i - 1);
}
}
return(sum);
//cout << sum;
}