⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 serialconnect.cpp

📁 在linux下把串口映射成TCP/IP端口
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		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 + -