📄 serialconnect.cpp
字号:
return g_baud_map[1].rate_const;
i = 0;
while (g_baud_map[i].rate_num >= 0)
{
if (g_baud_map[i+1].rate_num < 0)
{
res = g_baud_map[i].rate_const;
break;
}
if ((num > g_baud_map[i].rate_num) && (num <= g_baud_map[i+1].rate_num))
{
n1 = num - g_baud_map[i].rate_num;
n2 = g_baud_map[i+1].rate_num - num;
if (n1 > n2)
{
res = g_baud_map[i+1].rate_const;
}
else
{
res = g_baud_map[i].rate_const;
}
break;
}
i ++;
}
return res;
}
int OpenSerialPort (struct serial_port_info *port_info)
{
int fd, databit;
struct termios options;
if (!port_info)
{
printf ("Pointer error\n");
return -1;
}
fd = open (port_info->serialname, O_RDWR | O_NOCTTY | O_NDELAY);
if (fd == -1)
{
printf ("OpenSerailPort: file open error\n");
return -1;
}
fcntl (fd, F_SETFL, 0);
tcgetattr (fd, &options);
cfsetispeed (&options, GetBaudRate (port_info->baudrate));
cfsetospeed (&options, GetBaudRate (port_info->baudrate));
options.c_cflag |= (CLOCAL | CREAD);
printf("databit = %d\n",port_info->databit);
switch (port_info->databit)
{
case 5:
databit = CS5;
break;
case 6:
databit = CS6;
break;
case 7:
databit = CS7;
break;
case 8:
databit = CS8;
break;
default:
databit = CS8;
break;
}
options.c_cflag &= ~CSIZE;
options.c_cflag |= databit;
if (strcmp (port_info->stopbit, "STOPBITS_1") == 0)
{
options.c_cflag &= ~CSTOPB;
}
else
{
options.c_cflag |= CSTOPB;
}
if (strcmp (port_info->paritybit, "PARITY_NONE") == 0)
{
printf("%s parity_none\r\n",port_info->serialname);
options.c_cflag &= ~PARENB;
}
else if (strcmp (port_info->paritybit, "PARITY_EVEN") == 0)
{
printf("%s parity_even\r\n",port_info->serialname);
options.c_cflag |= PARENB;
options.c_cflag &= ~PARODD;
options.c_iflag |= (INPCK | ISTRIP);
}
else if (strcmp (port_info->paritybit, "PARITY_ODD") == 0)
{
printf("%s parity_odd\r\n",port_info->serialname);
options.c_cflag |= PARENB;
options.c_cflag |= PARODD;
options.c_iflag |= (INPCK | ISTRIP);
}
else
{
printf("%s parity_default\r\n",port_info->serialname);
options.c_cflag &= ~PARENB;
}
options.c_lflag &= ~(ICANON | ECHO | ECHOE | ISIG);
if (strcmp (port_info->insoftflowctrl, "ON") == 0)
options.c_iflag |= (IXON | IXOFF | IXANY);
else
options.c_iflag &= ~(IXON | IXOFF | IXANY);
options.c_oflag &= ~OPOST;
options.c_cc[VMIN] = 1;
options.c_cc[VTIME] = 0;
if ((strcmp (port_info->inhardflowctrl, "ON") == 0) ||
(strcmp (port_info->outhardflowctrl, "ON") == 0))
options.c_cflag |= CRTSCTS;
else
options.c_cflag &= ~CRTSCTS;
tcsetattr (fd, TCSANOW, &options);
fcntl (fd, F_SETFL, FNDELAY);
return fd;
}
int CreateServerSocket (int port_no)
{
int sock, res;
struct sockaddr_in myaddr;
sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock < 0)
{
printf ("Create socket error\n");
return -1;
}
bzero (&myaddr, sizeof (myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons (port_no);
myaddr.sin_addr.s_addr = htonl (INADDR_ANY);
res = bind (sock, (struct sockaddr *)&myaddr, sizeof (myaddr));
if (res < 0)
{
printf ("Bind error\n");
return -1;
}
listen (sock, 5);
return sock;
}
#define CONN_FD_MAX 5
#define MAX_READ_LEN 1024
int stop_flag;
int write_all (int fd, void *buf, int n)
{
int nleft, nbytes;
char *ptr;
nleft = n;
ptr = (char *)buf;
while (nleft > 0)
{
nbytes = write (fd, ptr, nleft);
if (nbytes < 0)
{
if (errno == EINTR)
nbytes = 0;
else
return nbytes;
}
nleft -= nbytes;
ptr += nbytes;
}
return 1;
}
void willexit (int sig_no)
{
printf ("Parent will exit\n");
stop_flag = 1;
}
void willexit_chld (int sig_no)
{
printf ("Child will exit\n");
stop_flag = 1;
}
int main (int argc, char *argv[])
{
int i, j, res, cur_port, status;
struct serial_port_info *p;
pid_t pid;
fd_set rds, wds;
int sd[CONN_FD_MAX];
int maxfd, nsels, navail, newsock, num;
if (argc != 2)
{
printf ("Usage: SerialConnect <config_file_name>\n");
return 0;
}
InitSerialPortMgr (&g_serial_port_mgr);
res = ReadConfigFile (argv[1]);
if (res < 0)
{
printf ("Error: read config file\n");
return 0;
}
stop_flag = 0;
p = g_serial_port_mgr.head;
while (p)
{
cur_port = p->serialno;
pid = fork ();
if (pid == 0)
{
struct serial_port_info *p_info;
int res, fd, sock;
char read_buf[MAX_READ_LEN];
signal (SIGINT, willexit_chld);
signal (SIGQUIT, willexit_chld);
signal (SIGABRT, willexit_chld);
signal (SIGFPE, willexit_chld);
signal (SIGKILL, willexit_chld);
signal (SIGTERM, willexit_chld);
signal (SIGHUP, SIG_IGN);
p_info = GetPortInfo (cur_port);
if (!p_info)
{
printf ("No port infomation\n");
exit (0);
}
PrintPortInfo (p_info);
fd = OpenSerialPort (p_info);
if (fd < 0)
{
printf ("Serial port open error\n");
exit (0);
}
sock = CreateServerSocket (p_info->portno);
if (sock < 0)
{
printf ("Server socket create error\n");
exit (0);
}
stop_flag = 0;
for (i = 0; i < CONN_FD_MAX; i ++)
sd[i] = -1;
navail = CONN_FD_MAX;
for (;stop_flag == 0;)
{
FD_ZERO (&rds);
FD_ZERO (&wds);
maxfd = 0;
if (navail > 0)
{
FD_SET (sock, &rds);
maxfd = sock;
}
FD_SET (fd, &rds);
maxfd = maxfd >= fd ? maxfd : fd;
for (i = 0; i < CONN_FD_MAX; i ++)
{
if (sd[i] > 0)
{
FD_SET (sd[i], &rds);
FD_SET (sd[i], &wds);
maxfd = maxfd > sd[i] ? maxfd : sd[i];
}
}
nsels = select (maxfd + 1, &rds, &wds, NULL, NULL);
if (nsels < 0)
{
if (errno == EINTR)
continue;
printf ("Select error: %s\n", strerror (errno));
break;
}
if (FD_ISSET (sock, &rds))
{
newsock = accept (sock, (struct sockaddr *)0, (socklen_t *)0);
if (newsock < 0)
{
printf ("Accept error: %s\n", strerror (errno));
break;
}
for (i = 0; i < CONN_FD_MAX; i ++)
{
if (sd[i] < 0)
break;
}
if (i < CONN_FD_MAX)
{
printf ("Socket connected(%d).\n", newsock);
sd[i] = newsock;
navail --;
}
nsels --;
}
for (i = 0; i < CONN_FD_MAX && nsels > 0; i ++)
{
if (sd[i] < 0)
continue;
if (FD_ISSET (sd[i], &rds))
{
num = read (sd[i], read_buf, MAX_READ_LEN);
if (num <= 0)
{
printf ("Socket disconnected(%d).\n", sd[i]);
close (sd[i]);
sd[i] = -1;
navail ++;
}
else
{
read_buf[num] = '\0';
for (j = 0; j < i; j ++)
{
if (sd[j] > 0)
break;
}
/*if (j >= i)*/ /*只有第一个socket连接可以发数据*/
/*由数据中心保证只有一个socket会发送数据,这儿不作判断*/
{
res = write_all (fd, read_buf, num);
if (res < 0)
{
printf ("Port %d write error\n", cur_port);
}
}
}
nsels --;
}
}
if (FD_ISSET (fd, &rds))
{
num = read (fd, read_buf, MAX_READ_LEN);
if (num < 0)
{
printf ("Serial port read error\n");
}
else if (num > 0)
{
read_buf[num] = '\0';
for (i = 0; i < CONN_FD_MAX && nsels > 0; i ++)
{
if (sd[i] < 0)
continue;
if (FD_ISSET (sd[i], &wds))
{
res = write_all (sd[i], read_buf, num);
if (res <= 0)
{
printf("Alarmintf: peer is closed(%d). \n", sd[i]);
close (sd[i]);
sd[i] = -1;
}
nsels --;
}
}
}
else
{
}
nsels --;
}
usleep (100);
}
for (i = 0; i < CONN_FD_MAX; i ++)
{
if (sd[i] > 0)
close (sd[i]);
}
close (fd);
exit (0);
}
else if (pid > 0)
{
p->chd_pid = pid;
}
else
{
printf ("fork error!\n");
p->chd_pid = -1;
}
p = p->next;
}
signal (SIGINT, willexit);
signal (SIGQUIT, willexit);
signal (SIGABRT, willexit);
signal (SIGFPE, willexit);
signal (SIGKILL, willexit);
signal (SIGTERM, willexit);
signal (SIGHUP, SIG_IGN);
signal (SIGCHLD, SIG_IGN);
while (stop_flag == 0)
{
pid = waitpid (-1, &status, WNOHANG);
if (pid < 0)
{
if (errno == EINTR)
{
continue;
}
else
{
printf ("Wait error: %s\n", strerror (errno));
break;
}
}
else if (pid == 0)
continue;
p = g_serial_port_mgr.head;
while (p)
{
if (p->chd_pid == pid)
break;
p = p->next;
}
if (p)
DelPortInfo (p);
usleep (100);
}
p = g_serial_port_mgr.head;
while (p)
{
if (p->chd_pid > 0)
kill (p->chd_pid, SIGKILL);
p = p->next;
}
DeinitSerialPortMgr (&g_serial_port_mgr);
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -