服务端和服务端通信
# 前言
前段时间在研究 IEC 60870-5-104规约,是一个广泛应用于电力、城市轨道交通等行业的国际标准。一般的使用场景是这样的:
- 主站和RTU之间使用 IEC 60870-5-104 规约进行通信,采用网络传输层的可靠传输协议TCP。
- 主站和从站处于同一局域网。
- 主站(控制侧)为TCP客户端,RTU(被控制端)为服务器端,即主站主动进行TCP连接,而RTU被动响应TCP连接。
# 需求
现应客户需求,RTU即服务器端放在局域网内,而主站即客户端要放在公网上。这样就存在一个问题,处在公网的客户端无法主动连接处于内网的服务器端(局域网IP的限制)。
# 引导
客户在IEC104使用方面有更丰富的经验,给我了点提示,让RTU先以客户端的身份去主动连接处在公网的服务器端(这时主站那边也不在担任客户端的角色的,因为它等待着被RTU连接,转而担任服务器端的角色),然后服务器端再通过这个连接,去继续IEC104规约的通信。
# 实现
只改了一行代码:Socket替换。
原始RTU代码(等待客户端连接部分)
Socket
ServerSocket_accept(ServerSocket self)
{
int fd;
Socket conSocket = NULL;
fd = accept(self->fd, NULL, NULL );
if (fd >= 0) {
conSocket = TcpSocket_create();
conSocket->fd = fd;
activateTcpNoDelay(conSocket);
}
return conSocket;
}
代码修改(Socket替换)
Socket
ServerSocket_accept(ServerSocket self)
{
int fd;
Socket conSocket = NULL;
// fd = accept(self->fd, NULL, NULL );
fd = sockfd; // sockfd为上一步RTU作为客户端客户端连接公网服务器的socket,
// 直接将此socket当作是从accept分配的socket,
// 服务端(公网TCP服务端)和服务端(局域网IEC104服务端)就能够
// 通过此socket进行互相通信了。
if (fd >= 0) {
conSocket = TcpSocket_create();
conSocket->fd = fd;
activateTcpNoDelay(conSocket);
}
return conSocket;
}
# 服务端和服务端通信
以上,利用TCP客户端的通信套接字,充当IEC104 Server部分通信套接字,从而达到服务端和服务端通信的目的。