|
|
|
@ -4,6 +4,7 @@
|
|
|
|
|
#include "database/database.h"
|
|
|
|
|
# include <winsock2.h>
|
|
|
|
|
# include <ws2tcpip.h>
|
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
#define REG_ADDR (header_length+1)
|
|
|
|
@ -19,7 +20,7 @@ using namespace std;
|
|
|
|
|
char slave_ip_addr[20] = { 0 }; //modbus slave tcp ip地址
|
|
|
|
|
unsigned short slave_tcp_port = TCP_PORT; //modbus slave tcp port端口号
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
extern int pro_delay_min;
|
|
|
|
|
|
|
|
|
|
ysp_modbus_regs_t ysp_modbus_data;
|
|
|
|
|
slave_add_t salve_addr = {0};
|
|
|
|
@ -66,6 +67,86 @@ void xSet_slave_port(const char* tcp_port)
|
|
|
|
|
printf("SLAVE_PORT is null,use default\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//创建 TCP Server socket
|
|
|
|
|
BYTE CreateTcpServerSock(int *LiSock, DWORD NetPort)
|
|
|
|
|
{
|
|
|
|
|
int i, tmp, ret, retval;
|
|
|
|
|
|
|
|
|
|
int len;
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
u_long largp = 1L; //非阻塞模式
|
|
|
|
|
char tmp_buf[256];
|
|
|
|
|
|
|
|
|
|
if (-1 < *LiSock)
|
|
|
|
|
return *LiSock;
|
|
|
|
|
|
|
|
|
|
if (NetPort == 0)
|
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
|
|
*LiSock = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP);
|
|
|
|
|
|
|
|
|
|
if (*LiSock < 0)
|
|
|
|
|
{
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 将socket设置为非阻塞模式
|
|
|
|
|
retval = ioctlsocket(*LiSock, FIONBIO, (u_long FAR*)&largp);
|
|
|
|
|
if (SOCKET_ERROR == retval)
|
|
|
|
|
{
|
|
|
|
|
// retval = WSAGetLastError();
|
|
|
|
|
// sprintf(tmp_buf, "ioctlsocket设置非阻塞模式错误, SocketError=%d, SocketId = %d", retval, *LiSock);
|
|
|
|
|
// DebugPrint(tmp_buf);
|
|
|
|
|
closesocket(*LiSock);
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
///设置socket的输入输出缓冲区大小
|
|
|
|
|
tmp = MODBUS_TCP_MAX_ADU_LENGTH;
|
|
|
|
|
setsockopt(*LiSock, SOL_SOCKET, SO_RCVBUF, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
tmp = MODBUS_TCP_MAX_ADU_LENGTH;
|
|
|
|
|
setsockopt(*LiSock, SOL_SOCKET, SO_SNDBUF, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
|
|
|
|
|
len = 4;
|
|
|
|
|
tmp_buf[0] = 1;
|
|
|
|
|
|
|
|
|
|
tmp = setsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, len);
|
|
|
|
|
tmp = getsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, &len);
|
|
|
|
|
tmp = 1;
|
|
|
|
|
// setsockopt(*LiSock, SOL_SOCKET, SO_KEEPALIVE, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
setsockopt(*LiSock, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
//set_keepalive(*LiSock, keep_alive, keep_idle, keep_interval, keep_count);
|
|
|
|
|
|
|
|
|
|
//让TCP接收所有连线
|
|
|
|
|
memset((char*)&addr, 0, sizeof(addr));
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
|
|
addr.sin_port = htons(NetPort);
|
|
|
|
|
addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
|
|
|
|
|
|
|
//printf("TIP_(%04d): Port = %d, NetCommIpAddr(%08x), addr.sin_addr.s_addr(%08x)\n", getpid(), commid+1, *NetCommIpAddr, addr.sin_addr.s_addr);
|
|
|
|
|
if (bind(*LiSock, (struct sockaddr *)&addr, sizeof(addr)) < 0)
|
|
|
|
|
{
|
|
|
|
|
//printf("errno = %d\n", errno);
|
|
|
|
|
//close(*LiSock);
|
|
|
|
|
closesocket(*LiSock);
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
//printf("succeed!\n");
|
|
|
|
|
|
|
|
|
|
ret = listen(*LiSock, 4);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
{
|
|
|
|
|
//close(*LiSock);
|
|
|
|
|
closesocket(*LiSock);
|
|
|
|
|
*LiSock = -1;
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
return *LiSock;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
char* com = (char*)lp;
|
|
|
|
|
CHAR rcv_buf[1024] = { 0 };
|
|
|
|
@ -85,12 +166,13 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
struct sockaddr_in addr;
|
|
|
|
|
socklen_t addrlen;
|
|
|
|
|
//struct tcp_info info;
|
|
|
|
|
time_t ictime, recvtime;
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
一次只接受一个主机master连接
|
|
|
|
|
即 accept 只接受一个客户端连接,该连接错误退出后,重新走到这里来accept
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (use_backend == TCP) {
|
|
|
|
|
ctx = modbus_new_tcp(slave_ip_addr, slave_tcp_port);
|
|
|
|
|
//modbus_set_slave(ctx, SERVER_ID);
|
|
|
|
@ -115,6 +197,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
modbus_free(ctx);
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for(;;){
|
|
|
|
|
if (use_backend == TCP) {
|
|
|
|
|
if (s < 0) {
|
|
|
|
@ -165,9 +248,11 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
else if (use_backend == TCP_PI) {
|
|
|
|
|
modbus_tcp_pi_accept(ctx, &s);
|
|
|
|
|
}
|
|
|
|
|
ictime = time(NULL);
|
|
|
|
|
recvtime = ictime;
|
|
|
|
|
std::cout << "modbus receive loop\n" << std::endl;
|
|
|
|
|
for (;;) {//循环接受消息
|
|
|
|
|
#if 1
|
|
|
|
|
#if 0
|
|
|
|
|
if (s < 0)
|
|
|
|
|
break;
|
|
|
|
|
FD_ZERO(&fdset_ro);
|
|
|
|
@ -188,8 +273,9 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
s = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
else if (FD_ISSET(s, &fdset_ro))// accept(*s, (struct sockaddr *) &addr, &addrlen);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
{
|
|
|
|
|
//std::cout << std::endl << "second accept wait connect (hold)\n" << std::endl;
|
|
|
|
|
extrasock = accept(s, (struct sockaddr *) &addr, &addrlen);
|
|
|
|
@ -207,7 +293,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
if (NULL == ctx)
|
|
|
|
|
return 0;
|
|
|
|
|
if (0 > sockt)
|
|
|
|
@ -218,6 +304,15 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
FD_SET(sockt, &fdset_ro);
|
|
|
|
|
FD_SET(sockt, &fdset_wr);
|
|
|
|
|
FD_SET(sockt, &fdset_ex);
|
|
|
|
|
ictime = time(NULL);
|
|
|
|
|
if (ictime - recvtime > pro_delay_min*10)
|
|
|
|
|
{
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
printf("TCP connection timeout of% d seconds, no valid data received", ictime - recvtime);
|
|
|
|
|
recvtime = ictime;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
memset((char*)&timeout, 0, sizeof(struct timeval));
|
|
|
|
|
if (select(sockt + 1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1)
|
|
|
|
|
{
|
|
|
|
@ -231,6 +326,21 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
sockt = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
#if 1
|
|
|
|
|
if (FD_ISSET(sockt, &fdset_wr))
|
|
|
|
|
{
|
|
|
|
|
int ierrlen, ierr;
|
|
|
|
|
|
|
|
|
|
ierrlen = sizeof(ierr);
|
|
|
|
|
rc = getsockopt(sockt, SOL_SOCKET, SO_ERROR, (char *)&ierr, &ierrlen);
|
|
|
|
|
if (SOCKET_ERROR == rc)
|
|
|
|
|
{
|
|
|
|
|
closesocket(sockt);
|
|
|
|
|
sockt = -1;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
if (FD_ISSET(sockt, &fdset_ro)) // 可读
|
|
|
|
|
{
|
|
|
|
|
do {
|
|
|
|
@ -268,6 +378,7 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
{
|
|
|
|
|
//int len = sizeof(info);
|
|
|
|
|
//getsockopt(sockt, IPPROTO_TCP, TCP_INFO, &info, (socklen t *)&len);if (info.tcpi state == TCP CLOSE WAIT && info.tcpi state != TCP ESTABLISHED)
|
|
|
|
|
#if 0
|
|
|
|
|
rc = recv(sockt, rcv_buf, 1,0);
|
|
|
|
|
if (rc <= 0)
|
|
|
|
|
{
|
|
|
|
@ -278,9 +389,12 @@ DWORD WINAPI xModbus_msg_ThreadProc(LPVOID lp) {
|
|
|
|
|
printf("Client TCP may unexpectedly interrupt!\n");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
Sleep(5);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
recvtime = time(NULL);
|
|
|
|
|
std::cout << "modbus new msg\n" << std::endl;
|
|
|
|
|
switch (query[header_length])
|
|
|
|
|
{
|
|
|
|
|