C/C++使用Socket模拟远程CMD

服务端(server)

#include <stdio.h>  
#include <winsock2.h>  
#pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库  
#define PORT 15001                    //通信的端口(指服务器端)
#define ERROR 0  
#define BUFFER_SIZE 1024            //注意:此Server端数据接收缓冲区 >= Client端数据发送缓冲区 ,否则造成缓冲区溢出
/*
    服务端原理:
        1、服务器进程创建套接字
        2、将本地地址绑定到所创建的套接字上,以三元组{<通信协议>,<IP地址>,<端口号>}在网络上标识该套接字
        3、将套接字置入监听模式,并准备接受连接请求
        4、接受请求之后,便可接收客户端发来的数据,并以本地DOS命令运行
*/
int main()  
{  
    WSADATA WSAData;  
    if(WSAStartup(MAKEWORD(2,0),&WSAData)==SOCKET_ERROR)  //启动winsock ,WSAStartup()函数对Winsock DLL进行初始化
    {  
        printf("Socket initialize fail!\n");  
        exit(1);  
    }  
    SOCKET sock;                                        //服务进程创建套接字句柄(用于监听)
    if((sock=socket(AF_INET,SOCK_STREAM,0))==ERROR)        //调用socket()函数创建一个流套接字,参数(网络地址类型,套接字类型,网络协议)
    { 
        printf("Socket create!\n");  
        WSACleanup();  
        exit(1);  
    }  
    struct sockaddr_in ServerAddr;            //sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构
    ServerAddr.sin_family=AF_INET;            //sin_family字段必须设为AF_INET,表示该Socket处于Internet域
    ServerAddr.sin_port=htons(PORT);        //sin_port字段用于指定服务端口,注意避免冲突
    ServerAddr.sin_addr.s_addr=INADDR_ANY;  //sin_addr字段用于把一个IP地址保存为一个4字节的数,无符号长整型,根据不同用法还可表示本地或远程IP地址
    if(bind(sock,(LPSOCKADDR)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)  //调用bind()函数将本地地址绑定到所创建的套接字上,以在网络上标识该套接字
    {   
        printf("Bind fail!\n");  
        closesocket(sock);  
        WSACleanup();  
        exit(1);  
    }  
    printf("Server Socket Port:%d\n",ntohs(ServerAddr.sin_port));  
    if(listen(sock,10)==SOCKET_ERROR)        //调用listen()函数将套接字置入监听模式并准备接受连接请求,参数(已捆绑未连接的套接字描述字,正在等待连接的最大队列长度)
    { 
        printf("Listen fail!\n");  
        closesocket(sock);  
        WSACleanup();  
        exit(1);  
    }  

SOCKET msgsock;            </span><span style="color: #008000;">//</span><span style="color: #008000;">创建一个新的套接字(用于接收accept函数的返回值,即表示已经接受的那个客户端的连接,进而接收Client发来的数据)</span>
<span style="color: #0000ff;">char</span> buf[BUFFER_SIZE];  <span style="color: #008000;">//</span><span style="color: #008000;">数据接收缓冲区</span>
<span style="color: #0000ff;">while</span>(<span style="color: #800080;">1</span><span style="color: #000000;">)  
{  
    </span><span style="color: #0000ff;">if</span>((msgsock=accept(sock,(LPSOCKADDR)<span style="color: #800080;">0</span>,(<span style="color: #0000ff;">int</span> *)<span style="color: #800080;">0</span>))==INVALID_SOCKET)  <span style="color: #008000;">//</span><span style="color: #008000;">进入监听状态后,调用accept()函数接收客户端的连接请求,并把连接传给msgsock套接字,原sock套接字继续监听其他客户机连接请求</span>

{
printf(
Accept fail!\n);
continue;
}
memset(buf,
0,sizeof(buf)); //初始化数据接收缓冲区
recv(msgsock,buf,BUFFER_SIZE,0); //接收客户端发送过来的数据
if(buf[0]==e && buf[1]==x && buf[2]==i && buf[3]==t) //“exit”命令,退出程序
{
printf(
The End.\n);
break;
}
printf(
C:\Socket\Server>%s,buf);
system(buf);
//本地运行客户端传来的命令:这一点太厉害了,假如传一个Format命令,那服务端可能就毁了
closesocket(msgsock);
}

closesocket(sock); </span><span style="color: #008000;">//</span><span style="color: #008000;">关闭套接字  </span>
WSACleanup();       <span style="color: #008000;">//</span><span style="color: #008000;">终止对Winsock DLL的使用,并释放资源</span>
<span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;

}

 

客户端(client)

#include <winsock2.h>  
#include <stdio.h>  
#pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库  
//#define IP "172.18.68.243"            //在两台计算机上测试,IP为Server端的IP地址  
#define IP "127.0.0.1"                //在一台计算机上测试,IP为本地回送地址
#define PORT 15001                    //注意:客户端设置通信的端口 = 服务端的端口
#define BUFFER_SIZE 1024            //数据发送缓冲区大小
/*
    客户端原理:
        1、客户端进程创建套接字
        2、客户端向服务端进程发出连接请求
        3、当服务端接受请求后,客户端便可向服务端发送数据
*/
int main()  
{  
    char buf[BUFFER_SIZE];                                //buf数组存放客户端发送的消息  
    int inputLen;                                        //用于输入字符自增变量
    while(1)  
    {  
        printf("C:\\Socket\\Client>");  
        inputLen=0;  
        memset(buf,0,sizeof(buf));  
        while((buf[inputLen++]=getchar())!='\n')        //输入以回车键为结束标识
        {
            ;
        }
        if(buf[0]=='e' && buf[1]=='x' && buf[2]=='i' && buf[3]=='t')  
        {  
            printf("The End.\n");  
            break;   
        }  

    WSADATA WSAData;  
    </span><span style="color: #0000ff;">if</span>(WSAStartup(MAKEWORD(<span style="color: #800080;">2</span>,<span style="color: #800080;">0</span>),&amp;WSAData)==SOCKET_ERROR)  <span style="color: #008000;">//</span><span style="color: #008000;">WSAStartup()函数对Winsock DLL进行初始化</span>

{
printf(
Socket initialize fail!\n);
continue;
}
SOCKET sock;
//客户端进程创建套接字
if((sock=socket(AF_INET,SOCK_STREAM,0))==SOCKET_ERROR) //创建流套接字(与服务端保持一致)
{
printf(
Socket create fail!\n);
WSACleanup();
continue;
}

    </span><span style="color: #0000ff;">struct</span> sockaddr_in ClientAddr;                <span style="color: #008000;">//</span><span style="color: #008000;">sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构</span>
    ClientAddr.sin_family=AF_INET;                <span style="color: #008000;">//</span><span style="color: #008000;">指Internet域</span>
    ClientAddr.sin_port=htons(PORT);            <span style="color: #008000;">//</span><span style="color: #008000;">指定服务端所预留的端口</span>
    ClientAddr.sin_addr.s_addr=inet_addr(IP);    <span style="color: #008000;">//</span><span style="color: #008000;">指定服务端所绑定的IP地址</span>
    <span style="color: #0000ff;">if</span>(connect(sock,(LPSOCKADDR)&amp;ClientAddr,<span style="color: #0000ff;">sizeof</span>(ClientAddr))==SOCKET_ERROR)  <span style="color: #008000;">//</span><span style="color: #008000;">调用connect()函数,向服务器进程发出连接请求  </span>

{
printf(
Connect fail!\n);
closesocket(sock);
WSACleanup();
continue;
}
send(sock,buf,BUFFER_SIZE,
0); //向服务器发送数据
closesocket(sock); //关闭套接字
WSACleanup(); //终止对Winsock DLL的使用,并释放资源,以备下一次使用
}
return 0;
}

 

客户端2(client)

#include <winsock2.h>  
#include <stdio.h>  
#pragma comment(lib,"ws2_32.lib")    //把ws2_32.lib加到Link页的连接库  
//#define IP "172.18.68.243"            //在两台计算机上测试,IP为Server端的IP地址  
#define IP "127.0.0.1"                //在一台计算机上测试,IP为本地回送地址
#define PORT 6666                    //注意:客户端设置通信的端口 = 服务端的端口

int main()
{
WSADATA WSAData;
SOCKET sock;

    WSAStartup(MAKEWORD(</span><span style="color: #800080;">2</span>, <span style="color: #800080;">0</span>), &amp;WSAData);     <span style="color: #008000;">//</span><span style="color: #008000;">== SOCKET_ERROR)  WSAStartup()函数对Winsock DLL进行初始化</span>
    sock = socket(AF_INET, SOCK_STREAM, <span style="color: #800080;">0</span><span style="color: #000000;">);

    </span><span style="color: #0000ff;">struct</span> sockaddr_in ClientAddr;                <span style="color: #008000;">//</span><span style="color: #008000;">sockaddr_in结构用来标识TCP/IP协议下的地址,可强制转换为sockaddr结构</span>
    ClientAddr.sin_family = AF_INET;                <span style="color: #008000;">//</span><span style="color: #008000;">指Internet域</span>
    ClientAddr.sin_port = htons(PORT);            <span style="color: #008000;">//</span><span style="color: #008000;">指定服务端所预留的端口</span>
    ClientAddr.sin_addr.s_addr = inet_addr(IP);    <span style="color: #008000;">//</span><span style="color: #008000;">指定服务端所绑定的IP地址</span>
connect(sock, (LPSOCKADDR)&ClientAddr, sizeof(ClientAddr));
    closesocket(sock);                             </span><span style="color: #008000;">//</span><span style="color: #008000;">关闭套接字</span>
    WSACleanup();                                <span style="color: #008000;">//</span><span style="color: #008000;">终止对Winsock DLL的使用,并释放资源,以备下一次使用</span>
<span style="color: #0000ff;">return</span> <span style="color: #800080;">0</span><span style="color: #000000;">;

}

 

 

 

 

 

参考文献:https://blog.csdn.net/lynch0571