说明:
在qnx官网有关于限制ssh数量的连接,即配置/etc/ssh/sshd_config文件,但是几乎将所有的参数都配置了一遍都不起作用,所有无奈之下只能用下面的方法以达到目的。
网址:http://netbsd.gw.com/cgi-bin/man-cgi?sshd_config+5+NetBSD-5.0
实现步骤:
1、qnx将ssh命令输出信息写入文件;
2、将文件数据读取出来;
3、读取文件内关于ssh的进程号;
4、杀掉多余限定的ssh连接(杀掉后连接的ssh进程,后连接的进程号>先连接的进程号)
潜在问题:以上实现是建立在打开同一个进程,后开启的进程号比先开启的进程号大
假如不是这样的,就会出现后连接的ssh把前面连接的ssh挤下去。
以下代码是根据项目需要完成,包括文件写入,读取,处理
时间紧迫,完成仓促,若有差错望指正
遇到的坑
第一次完成的时候,将存储数据的数组都定义在transformData()函数中;
这么写,可以完成一次上面的工作;但是第二次循环的时候会报以下错误:
Process 619962446 (ssh) terminated SIGSEGV code=1 fltno=11 ip=2020202020202020
Memory fault
解决办法:将存储数据的数组的定义从transformData()函数,变成全局变量。
分析:使用while(1)反复的在栈区分配数组的内存,再删除导致内存资源占用过多,反反复复操作导致栈区溢出,从而出现了内存错误。(个人理解,若不对请忽略。或请指正,在评论中回复)
实现方法
#include<stdio.h>
#include <stdlib.h>
#include <string.h>
#include “string”//用<>替换 “”
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#define MAX_SSH 3
#define MAX_FILEDATA 1024
#define MAX_SSH_COUNT 100
#define MAX_SSH_LINEDATA_LEN 200
#define MAX_SSH_PROCESS_LEN 20
#define MAX_SSH_CMD_LEN 20
char buf[MAX_FILEDATA];//save 文件内容
unsigned int lineCount;//文件内的行数,即ssh连接数量
char str[MAX_SSH_COUNT][MAX_SSH_LINEDATA_LEN];//分别保存文件内容每一行数据
char processNo[MAX_SSH_COUNT][MAX_SSH_PROCESS_LEN];//保存所有ssh的进程号
long charTolong[MAX_SSH_COUNT];//保存全部ssh进程id转
char cmd[MAX_SSH_CMD_LEN];//保存删除ssh进程的命令
int processNoLen = 0;
int totalLen = 0;//用于整个文件内容长度遍历
bool flag = 0;//每个ssh进程在文件内都是单独一行,记录读取文件一行结束
//初始化
void init()
{
memset(buf,0,sizeof(buf));
lineCount=0;
memset(str,0,sizeof(str));
memset(processNo,0,sizeof(processNo));
memset(charTolong,0,sizeof(charTolong));
memset(cmd,0,sizeof(0));
processNoLen = 0;
totalLen = 0;
flag = 0;
}
//将文件写入ssh.txt
void getSshData()
{
//使用system函数直接调用ssh命令
system(“pidin -p sshd | grep sshd > ssh.txt”);
}
//读取文件内容,并返回文件行数
int file_get(const char *filename)
{
int fd;
register int linect = 0;
int len;
char *p = NULL;
if(filename) {
//打开指定的文件
if((fd = open(filename, O_RDONLY)) < 0) {
fprintf(stderr, “open failed\n”);
return -1;
}
while(1) {
//将文件内数据读取到buf数组中
if((len = read(fd,buf,MAX_FILEDATA)) == -1) {
return -1;
}
if(len == 0){
break;
}
//计算文件的行数
for( p = buf; len--; ){
if( *p == '\n' ){
++linect;
}
++p;
}
}
}
close(fd);
//printf(“wubw test \n %s \n”,std::string(buf).c_str());
return linect;
}
//冒泡排序
void sort(long *arr,int sz){
int i = 0;
int j = 0;
//assert(arr);
for(i=0;i<sz-1;i++){
for(j=0;j<sz-i-1;j++){
if(arr[j]>arr[j+1]){
int tmp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = tmp;
}
}
}
}
//将文件内获取到的进程号转化成long数组,并排序,删除大于MAX_SSH数量的ssh进程
//返回ssh进程的个数
int transformData()
{
lineCount = file_get(“ssh.txt”);
//从第一行开始遍历文件内容,文件数据如上图所示
for(int i=0;i<lineCount;i++)
{
flag = 1;//用于记录1行遍历结束,进入下一行则变为true
//从0~MAX_FILEDATA 开始遍历文件内容
while(totalLen++<MAX_FILEDATA)
{
if(buf[totalLen] != ‘\n’)
{
str[i][totalLen] = buf[totalLen];//用于存储每一行的数据
//根据文件内的特殊性,判断当 1.字符不为null 2.是0<num<9的值 3.没有到换行符
if(buf[totalLen] != ‘\0’ && ((buf[totalLen]>=‘0’)&&(buf[totalLen]<=‘9’)) && flag)
{
processNo[i][processNoLen++] = buf[totalLen];//保存进程号
}
else
{
flag = 0;//重新开始另一行
processNoLen = 0;//从0开始存储另一个进程号
}
}
else
{
str[i][totalLen] = ‘\0’;//一行的数据结束符
break;//退出这一行的循环
}
}
charTolong[i] = atol(processNo[i]);//char to long
//printf("str[%d] = %ld \n",i , charTolong[i]);
}
sort(charTolong,lineCount);//排序
return lineCount;//返回文件内容的行数
}
void deleteMoreSSH(int value)
{
//删除多余的ssh
while(value > MAX_SSH)//判断传入的行数是否 > 允许连接的最大行数
{
value–;
//拼接cmd命令,将ssh的进程号写入cmd中
sprintf(cmd,“kill -9 %ld”, charTolong[value]);
system(cmd);
}
}
void processData()
{
while(true)
{
try
{
init();
getSshData();
transformData();
deleteMoreSSH(lineCount);
//每隔1S检测一次
usleep(1000000);
}
catch(char *str)
{
printf("\n catch error : %s \n",str );
}
}
}
int main(int argc, char *argv[])
{
processData();
return 0;
}