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;
}