LibSSH2库封装类

 libssh2学习---直入主题封装类

 ssh2.h

#ifndef _SSH2_
#define _SSH2_

#include <string>
#include <thread>
#include <atomic>
#include "libssh2.h"


class SSH2
{
public:
	SSH2();
	SSH2(std::string ip, int port=22);
	~SSH2();

	//初始化网络资源与ssh资源
	static bool InitNetResource();
	//释放网络资源与ssh资源
	static bool ReleaseNetResource();

	//连接对端服务器
	bool ConnectionSer(std::string login_name, std::string login_password);
	bool ConnectionSer(std::string ip, int port, std::string login_name, std::string login_password);

	//执行命令
	bool ExecuteCommand(std::string cmd);

private:
	void ReciverMsgThdFun();
	int waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION* session);

	//使用正则表达式校验ip格式
	bool isIP(std::string ip);

private:
	static bool isInitResource;

	std::string m_ip;
	int  m_port;

	std::thread m_thread;
	std::atomic<bool> m_isStop;

	libssh2_socket_t m_sock;
	LIBSSH2_SESSION* m_session;
	LIBSSH2_CHANNEL* m_channel;
};


#endif // SSH2


 ssh2.cpp

#include "SSH2.h"
#include <winsock2.h>
#include <stdio.h>
#include <functional>
#include <regex>


bool SSH2::isInitResource = false;

SSH2::SSH2()
{
	m_session = NULL;
	m_channel = NULL;
	m_isStop = false;
}

SSH2::SSH2(std::string ip, int port):
	m_ip(ip),m_port(port)
{
	m_session = NULL;
	m_channel = NULL;
	m_isStop = false;
}

SSH2::~SSH2()
{
	m_isStop = true;
	if (m_thread.joinable())
	{
		m_thread.join();
	}
	if (m_channel) {
		libssh2_channel_close(m_channel);
		libssh2_channel_free(m_channel);
	}
	if (m_session) {
		libssh2_session_disconnect(m_session, "Normal Shutdown");
		libssh2_session_free(m_session);
	}
	if (m_sock != LIBSSH2_INVALID_SOCKET) {
		shutdown(m_sock, 2);
		LIBSSH2_SOCKET_CLOSE(m_sock);
	}
	m_session = NULL;
	m_channel = NULL;
}

bool SSH2::InitNetResource()
{
	if (isInitResource) {
		fprintf(stderr, "Initialize the resource repeatedly!!!\n");
		return false;
	}

	WSADATA wsadata;
	int rc = WSAStartup(MAKEWORD(2, 0), &wsadata);
	if (rc) {
		fprintf(stderr, "WSAStartup failed with error: %d\n", rc);
		return false;
	}

	rc = libssh2_init(0);
	if (rc) {
		WSACleanup();
		fprintf(stderr, "libssh2 initialization failed (%d)\n", rc);
		return false;
	}

	isInitResource = true;

	return true;
}

bool SSH2::ReleaseNetResource()
{
	if (isInitResource) {
		libssh2_exit();

		int rc = WSACleanup();
		if (rc) {
			fprintf(stderr, "WSACleanup failed with error: %d\n", rc);
			return false;
		}

		isInitResource = false;
	}
	else {
		fprintf(stderr, "Release the resource repeatedly!!!\n");
		return false;
	}
	return true;
}

bool SSH2::ConnectionSer(std::string login_name, std::string login_password)
{
	return false;
}

bool SSH2::ConnectionSer(std::string ip, int port, std::string login_name, std::string login_password)
{
	if (!isIP(ip)) {
		fprintf(stderr, "ip format error!!!.\n");
		return false;
	}

	m_ip = ip;
	m_port = port;

	m_sock = socket(AF_INET, SOCK_STREAM, 0);
	if (m_sock == LIBSSH2_INVALID_SOCKET) {
		fprintf(stderr, "failed to create socket.\n");
		return false;
	}

	struct sockaddr_in sin;
	sin.sin_addr.s_addr = inet_addr(m_ip.c_str());
	sin.sin_family = AF_INET;
	sin.sin_port = htons(m_port);

	if (connect(m_sock, (struct sockaddr*)(&sin), sizeof(struct sockaddr_in))) {
		fprintf(stderr, "failed to connect remote ip=%s.\n", m_ip.c_str());
		return false;
	}

	/* Create a session instance */
	m_session = libssh2_session_init();
	if (!m_session) {
		fprintf(stderr, "Could not initialize SSH session.\n");
		return false;
	}

	/* tell libssh2 we want it all done non-blocking */
	libssh2_session_set_blocking(m_session, 0);

	/* ... start it up. This will trade welcome banners, exchange keys,
	 * and setup crypto, compression, and MAC layers
	 */
	int rc;
	while ((rc = libssh2_session_handshake(m_session, m_sock)) ==LIBSSH2_ERROR_EAGAIN);
	if (rc) {
		fprintf(stderr, "Failure establishing SSH session: %d\n", rc);
		return false;
	}

	if (strlen(login_password.c_str()) != 0) {
		/* We could authenticate via password */
		while ((rc = libssh2_userauth_password(m_session, login_name.c_str(), login_password.c_str())) ==LIBSSH2_ERROR_EAGAIN);
		if (rc) {
			fprintf(stderr, "Authentication by password failed.\n");
			return false;
		}
	}else {
		return false;
	}

	/* Exec non-blocking on the remote host */
	do {
		m_channel = libssh2_channel_open_session(m_session);
		if (m_channel ||
			libssh2_session_last_error(m_session, NULL, NULL, 0) !=
			LIBSSH2_ERROR_EAGAIN)
			break;
		//waitsocket(m_sock, m_session);
	} while (1);

	if (!m_channel) {
		fprintf(stderr, "Error\n");
		return false;
	}

	//开启线程
	m_thread = std::thread(std::bind(&SSH2::ReciverMsgThdFun, this));

	return true;
}

bool SSH2::ExecuteCommand(std::string cmd)
{
	int rc;
	while ((rc = libssh2_channel_exec(m_channel, cmd.c_str())) ==
		LIBSSH2_ERROR_EAGAIN) {
		waitsocket(m_sock, m_session);
	}
	if (rc) {
		fprintf(stderr, "exec error code= %d\n",rc);
		return false;
	}
}

void SSH2::ReciverMsgThdFun()
{
	ssize_t bytecount = 0;
	for (;;) {
		if (m_isStop) {
			break;
		}
		ssize_t nread;
		/* loop until we block */
		do {
			char buffer[0x4000];
			nread = libssh2_channel_read(m_channel, buffer, sizeof(buffer));
			if (nread > 0) {
				ssize_t i;
				bytecount += nread;
				fprintf(stderr, "We read:\n");
				for (i = 0; i < nread; ++i)
					fputc(buffer[i], stderr);
				fprintf(stderr, "\n");
			}
			else {
				if (nread != LIBSSH2_ERROR_EAGAIN)
					/* no need to output this for the EAGAIN case */
					fprintf(stderr, "libssh2_channel_read returned %ld\n",(long)nread);
			}
		} while (nread > 0);

		/* this is due to blocking that would occur otherwise so we loop on
		   this condition */
		if (nread == LIBSSH2_ERROR_EAGAIN) {
			waitsocket(m_sock, m_session);
		}
		else {
			fprintf(stderr, "thread exit!!!\n");
			break;
		}
	}
}

int SSH2::waitsocket(libssh2_socket_t socket_fd, LIBSSH2_SESSION* session)
{
	struct timeval timeout;
	int rc;
	fd_set fd;
	fd_set* writefd = NULL;
	fd_set* readfd = NULL;
	int dir;

	timeout.tv_sec = 10;
	timeout.tv_usec = 0;

	FD_ZERO(&fd);

	FD_SET(socket_fd, &fd);

	/* now make sure we wait in the correct direction */
	dir = libssh2_session_block_directions(session);

	if (dir & LIBSSH2_SESSION_BLOCK_INBOUND)
		readfd = &fd;

	if (dir & LIBSSH2_SESSION_BLOCK_OUTBOUND)
		writefd = &fd;

	rc = select((int)(socket_fd + 1), readfd, writefd, NULL, &timeout);

	return rc;
}

bool SSH2::isIP(std::string ip)
{
	std::regex pattern("((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)");
	std::smatch res;
	if (regex_match(ip, res, pattern)) {
		return true;
	}
	else {
		return false;
	}
}

 main.cpp

#include <iostream>
#include "SSH2.h"

int main() {
	SSH2::InitNetResource();
	SSH2::InitNetResource();
	SSH2::InitNetResource();
	SSH2::InitNetResource();
	SSH2::InitNetResource();
	SSH2::InitNetResource();
	{
		SSH2 s;
		std::string ip = "***.***.***.***";
		int port = 22;
		std::string name = "root";
		std::string password = "*********";
		if (s.ConnectionSer(ip, port, name, password)) {
			s.ExecuteCommand("ls -l;");
		}
		Sleep(5000);
	}

	SSH2::ReleaseNetResource();
	SSH2::ReleaseNetResource();
	SSH2::ReleaseNetResource();
	SSH2::ReleaseNetResource();

	//system("pause");

	return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值