串口服务器是为RS-232/485/422串口到TCP/IP网络之间完成数据转换的通讯接口转换器。提供RS-232/485/422终端串口与TCP/IP网络的数据双向透明传输,提供串口转网络功能,RS-232/485/422转网络的解决方案,可以让串口设备立即联接网络。
MOXA工业级串口服务器
应用领域
门禁系统、考勤系统、售饭系统、 POS 系统、楼宇自控系统、自助银行系统电信机房监控,电力监控等。
产品特点
·体积小,火柴盒大小
·支持RS232,RS485
·
10/
100M以太网口 ,软件可升级
·一个开关量输入,一个开关量输出
·可作为TCP Server 或TCP Client ,UDP数据
·内置WEB服务器,支持Java
·支持多种异步串口格式
·无需修改原有应用软件就可在网络环境下使用
·将
COM口定向至IP地址,每台计算机可同时拥有
256个串口
工作方式
服务器方式:在该工作方式下,串口联网服务器作为TCP服务器端, 转换器在指定的TCP端口上监听平台程序的连接请求,该方式比较适合于一个转换器与多个平台程序建立连接(一个转换器不能同时与多个平台程序建立连接)。
客户端方式:在该工作方式下,串口联网服务器 作为 TCP 客户端,转换器上电时主动向平台程序请求连接,该方式比较适合于多个转换器同时向一个平台程序建立连接。
通讯模式
点对点通讯模式:该模式下,转换器成对的使用,一个作为服务器端,一个作为客户端,两者之间建立连接,实现数据的双向透明传输。该模式适用于将两个串口设备之间的总线连接改造为 TCP/IP 网络连接。 使用虚拟串口通讯模式:该模式下,一个或者多个转换器与一台电脑建立连接,实现数据的双向透明传输。由电脑上的虚拟串口软件管理下面的转换器,可以实现一个虚拟串口对应多个转换器, N 个虚拟串口对应 M 个转换器( N<=M )。该模式适用于串口设备由电脑控制的 485 总线或者 232 设备连接。 基于网络通讯模式: 该模式下,电脑上的应用程序基于SOCKET 协议编写了通讯程序,在转换器设置上直接选择支持 SOCKET 协议即可。
实现原理
ARM开发板 一般的开发板都可使用,只要带有网口(有线/无线)、串口。
开发板串口服务端源码
#include <stdlib.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include <termios.h> /*PPSIX终端控制定义*/
#include <errno.h> /*错误号定义*/
#define COM_FILE "/dev/ttySAC0"
#define PORT 8848
#define BACKLOG 5
#define MAXDATASIZE 128
#define BUFSIZE 512
void* net_proc(
void* arg);
void* net_recv(
void* arg);
void* net_send(
void* arg);
void* com_recv(
void* arg);
void* com_send(
void* arg);
int init_com(
void);
struct ARG {
int connfd;
struct sockaddr_in client;
};
static char net_buff[BUFSIZE];
static char com_buff[BUFSIZE];
int wr_index =
0;
int re_index =
0;
int main(
void)
{
int fd =
0;
pthread_t net_th, com_r,com_s;
memset(net_buff,
0,BUFSIZE);
memset(com_buff,
0,BUFSIZE);
if((fd = init_com())<=
0){
perror(
"init_com() error");
exit(
1);
}
if(pthread_create(&net_th, NULL, net_proc, NULL)){
perror(
"pthread_creat() error");
exit(
1);
}
if(pthread_create(&com_r, NULL, com_recv, (
void*)&fd)){
perror(
"pthread_creat() error");
exit(
1);
}
if(pthread_create(&com_s, NULL, com_send, (
void*)&fd)){
perror(
"pthread_creat() error");
exit(
1);
}
pthread_join(net_th,NULL);
pthread_join(com_r,NULL);
pthread_join(com_s,NULL);
}
void* net_proc(
void* arg)
{
int listenfd, connectfd;
pthread_t thread;
struct ARG *acc_arg;
struct sockaddr_in server;
struct sockaddr_in client;
int sin_size;
printf(
"socket.... ");
if ((listenfd = socket(AF_INET, SOCK_STREAM,
0)) == -
1){
perror(
"creating socket failed.");
exit(
1);
}
bzero(&server,
sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr.s_addr = htonl(INADDR_ANY);
printf(
"bind.... ");
if(bind(listenfd,(
struct sockaddr *)&server,
sizeof(
struct sockaddr)) == -
1){
perror(
"bind error.");
exit(
1);
}
printf(
"listen.... ");
if(listen(listenfd,BACKLOG) == -
1) {
perror(
"listen() error ");
exit(
1);
}
sin_size =
sizeof(
struct sockaddr_in);
sleep(
1);
while(
1){
printf(
"accepting....\n ");
if((connectfd = accept(listenfd,(
struct sockaddr *)&client,(socklen_t*)&sin_size)) == -
1) {
perror(
"accept() error ");
exit(
1);
}
acc_arg =
malloc(
sizeof(
struct ARG));
acc_arg->connfd = connectfd;
memcpy((
void *)&acc_arg->client, &client,
sizeof(client));
if(pthread_create(&thread, NULL, net_recv, (
void*)acc_arg)){
perror(
"pthread_creat() error");
exit(
1);
}
if(pthread_create(&thread, NULL, net_send, (
void*)acc_arg)){
perror(
"pthread_creat() error");
exit(
1);
}
}
close(listenfd);
return (
0);
}
void* net_recv(
void* arg)
{
int connectfd;
int nbyte;
char recvbuf[MAXDATASIZE];
struct sockaddr_in client;
struct ARG * n_arg = arg;
connectfd = n_arg->connfd;
client = n_arg->client;
printf(
"IP: %s. \n",inet_ntoa(client.sin_addr) );
while(
1){
memset(recvbuf,
0,MAXDATASIZE);
nbyte = recv(connectfd, recvbuf, MAXDATASIZE,
0);
if(nbyte==
0 || nbyte == -
1) {
close(connectfd);
perror(
"Client disconnected. ");
break;
}
recvbuf[nbyte] =
'\0';
printf(
"fd=%d nbyte=%d net recv: %s \n", connectfd,nbyte,recvbuf );
strcat(net_buff,recvbuf);
}
}
void* net_send(
void* arg)
{
int connectfd;
int nbyte;
struct ARG * n_arg = arg;
connectfd = n_arg->connfd;
while(
1){
if(
strlen(com_buff)>
0)
{
nbyte = send(connectfd, com_buff,
strlen(com_buff),
0);
printf(
"net send nbyte=%d\n",nbyte);
memset(com_buff,
'\0', BUFSIZE);
}
}
}
int init_com(
void)
{
int fd_com;
struct termios initial_settings, new_settings;
fd_com = open(COM_FILE, O_RDWR | O_NOCTTY );
if(-
1 == fd_com)
{
perror(
"Can't Open Serial Port");
return -
1;
}
tcgetattr(fd_com,&initial_settings);
new_settings = initial_settings;
cfsetispeed(&new_settings, B115200);
cfsetospeed(&new_settings, B115200);
new_settings.c_cflag |= CS8;
new_settings.c_cflag &= ~CSTOPB;
new_settings.c_cflag &= ~PARENB;
new_settings.c_iflag &= ~INPCK;
new_settings.c_iflag |= IGNPAR;
new_settings.c_iflag |= ICRNL;
new_settings.c_oflag =
0;
new_settings.c_lflag &= ~ICANON;
new_settings.c_lflag &= ~ISIG;
new_settings.c_cc[VMIN] =
1;
new_settings.c_cc[VTIME] =
0;
if(tcsetattr(fd_com, TCSANOW, &new_settings) !=
0) {
fprintf(stderr,
"could not set attributes\n");
}
return fd_com;
}
void* com_send(
void* arg)
{
int fd;
int nbyte;
fd = *(
int*)arg;
while(
1)
{
if(
strlen(net_buff)>
0)
{
nbyte = write(fd,net_buff,
strlen(net_buff));
printf(
"com send nbyte=%d\n",nbyte);
memset(net_buff,
'\0',
sizeof(net_buff));
}
}
}
void* com_recv(
void* arg)
{
int fd;
int nbyte =
0;
fd = *(
int*)arg;
char recvbuf[MAXDATASIZE];
while(
1)
{
memset(recvbuf,
'\0',MAXDATASIZE);
nbyte =
0;
nbyte = read(fd,recvbuf,MAXDATASIZE);
recvbuf[nbyte] =
'\0';
printf(
"nbyte=%d com recv:%s\n",nbyte,recvbuf);
strcat(com_buff,recvbuf);
}
}
PC客户端源程序
#include <stdio.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <netdb.h>
#include <unistd.h>
#include <string.h>
#include <arpa/inet.h>
#include <errno.h>
#include <stdlib.h>
#include <pthread.h>
#define PORT
8848
#define MAXDATASIZE
128
void* net_recv(
void* arg);
void* net_send(
void* arg);
int get_line(
char *msg);
int init_net(
int argc,
char *argv[]);
/**********************************
主函数
**********************************/
int main(
int argc,
char *argv[])
{
int net_fd;
pthread_t recv_th,send_th;
net_fd = init_net(argc,argv);
pthread_create(&send_th,NULL,net_send,(
void*)&net_fd);
pthread_create(&recv_th,NULL,net_recv,(
void*)&net_fd);
pthread_join(recv_th,NULL);
pthread_join(send_th,NULL);
return 0;
}
/**********************************
网络接收线程
**********************************/
void* net_recv(
void* arg)
{
char recvline[MAXDATASIZE];
int *sockfd;
int numbytes;
sockfd = (
int*)arg;
while(
1){
printf(
"@\n");
if((numbytes = recv(*sockfd, recvline, MAXDATASIZE,
0)) ==
0){
printf(
"serial not data. \n");
}
recvline[numbytes] =
'\0';
printf(
"[com data] %s\n", recvline);
memset(recvline,
'0', strlen(recvline)-
1);
}
}
/**********************************
网络初始化,连接到服务端
**********************************/
int init_net(
int argc,
char *argv[])
{
int fd;
struct hostent *he;
struct sockaddr_in server;
char *defaultIP =
"127.0.0.1";
if(argc !=
2) {
if((he = gethostbyname(defaultIP)) == NULL){
perror(
"gethostbyname() error");
exit(
1);
}
}
else{
if((he = gethostbyname(argv[
1])) == NULL){
perror(
"gethostbyname() error");
exit(
1);
}
}
if((fd = socket(AF_INET, SOCK_STREAM,
0)) == -
1){
perror(
"socket() error");
exit(
1);
}
bzero(&server , sizeof(server));
server.sin_family = AF_INET;
server.sin_port = htons(PORT);
server.sin_addr = *((struct in_addr *)he->h_addr);
if(connect(fd, (struct sockaddr *)&server,sizeof(struct sockaddr)) == -
1){
perror(
"connect() error");
exit(
1);
}
return fd;
}
/**********************************
网络发送数据线程
**********************************/
void* net_send(
void* arg)
{
char sendline[MAXDATASIZE],recvline[MAXDATASIZE];
int numbytes;
int len;
int * sock_fd;
sock_fd = (
int*)arg;
printf(
"connected to server. \n");
while(
1){
while((len =get_line(sendline)) !=
0){
sendline[len] =
'\0';
send(*sock_fd, sendline, strlen(sendline),
0);
}
}
}
/**********************************
接收命令行输入的数据
**********************************/
int get_line(
char *msg)
{
int i=
0;
char temp;
printf(
"Input message:");
fflush(stdout);
while (
1) {
temp = getchar();
if (temp ==
'\r' || temp ==
'\n') {
return i ;}
msg[i]=temp;
if(msg[i]==
13){
msg[i]=
0;
break;
}
fflush(stdout);
i++;
}
}