获取Windows Shell的简单示例程序<二>
程序基本流程:
1,创建服务端Socket,端口绑定,监听。
这也是一般的socket程序的处理流程。
2,启动循环并在循环体中接收客户端请求并返回客户端套接字。
3,启动子线程处理当前连接。在子线程中进行cmd子进程的创建及数据的发送和接受。其中子进程的输入输出重定向如下:
3.1,创建读写管道.
3.2,创建cmd子进程,将设置cmd的输入输出句柄为管道句柄.
未完待续.
程序代码:
1,创建服务端Socket,端口绑定,监听。
这也是一般的socket程序的处理流程。
2,启动循环并在循环体中接收客户端请求并返回客户端套接字。
3,启动子线程处理当前连接。在子线程中进行cmd子进程的创建及数据的发送和接受。其中子进程的输入输出重定向如下:
3.1,创建读写管道.
3.2,创建cmd子进程,将设置cmd的输入输出句柄为管道句柄.
未完待续.
程序代码:
Code
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32");
//线程参数
struct THREADPARAM{
SOCKET socket;//客户端连接套接字.
HANDLE hReadShell;//shell的读管道句柄.
HANDLE hWriteShell;//shell的写管道句柄.
};
//接收线程
DWORD WINAPI RecvFunc(LPVOID lpParam);
//发送线程
DWORD WINAPI SendFunc(LPVOID lpParam);
void main()
{
WSADATA wsaData;
int err;
err=WSAStartup(MAKEWORD(2,2),&wsaData);
if(err != 0){
printf("WSAStartup failed\r\n");
return;
}
if(LOBYTE(wsaData.wVersion) != 2||
HIBYTE(wsaData.wVersion) != 2){
WSACleanup();
return;
}
//创建服务端套接字
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(1234);
//绑定端口
bind(sockSrv,(SOCKADDR *)&addrSrv,sizeof(SOCKADDR));
//监听
listen(sockSrv,5);
while(1){
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
SOCKET sockClient=accept(sockSrv,(SOCKADDR *)&addrClient,&len);
if(sockClient == INVALID_SOCKET){
printf("Invalid client socket!\r\n");
break;
}
//安全属性
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
HANDLE hReadPipe,hWritePipe;
HANDLE hWriteShell,hReadShell;
//创建管道
if(!CreatePipe(&hReadPipe,&hWriteShell,&sa,NULL)){
printf("Create anomyous pipe failed!\r\n");
break;
};
if(!CreatePipe(&hReadShell,&hWritePipe,&sa,NULL)){
printf("Create anomyous pipe failed!\r\n");
break;
};
//设置启动参数并启动shell子进程
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo,sizeof(STARTUPINFO));
startupInfo.cb=sizeof(STARTUPINFO);
startupInfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
startupInfo.hStdInput =hReadPipe;
startupInfo.hStdOutput=hWritePipe;
startupInfo.hStdError = hWritePipe;
startupInfo.wShowWindow=SW_SHOW;
PROCESS_INFORMATION pi;
CreateProcess(NULL,"cmd",NULL,NULL,
TRUE,0,NULL,NULL,&startupInfo,&pi);
DWORD threadId1,threadId2;
THREADPARAM tp;
tp.socket=sockClient;
tp.hReadShell=hReadShell;
tp.hWriteShell=hWriteShell;
HANDLE h1=CreateThread(NULL,0,RecvFunc,(LPVOID)&tp,NULL,&threadId1);
HANDLE h2= CreateThread(NULL,0,SendFunc,(LPVOID)&tp,NULL,&threadId2);
//WaitForSingleObject(h1,INFINITE);
//WaitForSingleObject(h2,INFINITE);
}
closesocket(sockSrv);
WSACleanup();
return ;
}
DWORD WINAPI RecvFunc(LPVOID lpParam){
THREADPARAM *pParam=(THREADPARAM *)lpParam;
char buf[4096];
while(1){
if(pParam->socket == INVALID_SOCKET){
return 0;
}
memset(buf,0,4096);
DWORD dwRecvLen=recv(pParam->socket,buf,100,0);
if(dwRecvLen <= 0){
closesocket(pParam->socket);
pParam->socket=INVALID_SOCKET;
return 0;
}
DWORD dwBytesWritten;
WriteFile(pParam->hWriteShell,buf,dwRecvLen,&dwBytesWritten,0);
printf("In RecvFunc:\nsocket=0x%08x\r\n",pParam->socket);
printf("Write %d bytes:%s,%d bytes writen actually\r\n",dwRecvLen,buf,dwBytesWritten);
}
return 0;
}
DWORD WINAPI SendFunc(LPVOID lpParam){
THREADPARAM *pParam=(THREADPARAM *)lpParam;
char buf[4096];
while(1){
if(pParam->socket == INVALID_SOCKET)
return 0;
memset(buf,0,4096);
DWORD dwRead=0;
ReadFile(pParam->hReadShell,buf,100,&dwRead,0);
if(dwRead != 0){
int ret=send(pParam->socket,buf,dwRead+1,0);
printf("In SendFunc:\nsocket=0x%08x\r\n",pParam->socket);
printf("Read %d bytes:%s\r\nSend",dwRead,buf);
}
}
return 0;
}
程序在处理客户端断开连接时还未加处理.欢迎读者给我提出一些意见和建议.
#include <stdio.h>
#include <winsock2.h>
#pragma comment(lib,"ws2_32");
//线程参数
struct THREADPARAM{
SOCKET socket;//客户端连接套接字.
HANDLE hReadShell;//shell的读管道句柄.
HANDLE hWriteShell;//shell的写管道句柄.
};
//接收线程
DWORD WINAPI RecvFunc(LPVOID lpParam);
//发送线程
DWORD WINAPI SendFunc(LPVOID lpParam);
void main()
{
WSADATA wsaData;
int err;
err=WSAStartup(MAKEWORD(2,2),&wsaData);
if(err != 0){
printf("WSAStartup failed\r\n");
return;
}
if(LOBYTE(wsaData.wVersion) != 2||
HIBYTE(wsaData.wVersion) != 2){
WSACleanup();
return;
}
//创建服务端套接字
SOCKET sockSrv=socket(AF_INET,SOCK_STREAM,0);
SOCKADDR_IN addrSrv;
addrSrv.sin_addr.S_un.S_addr=htonl(INADDR_ANY);
addrSrv.sin_family=AF_INET;
addrSrv.sin_port=htons(1234);
//绑定端口
bind(sockSrv,(SOCKADDR *)&addrSrv,sizeof(SOCKADDR));
//监听
listen(sockSrv,5);
while(1){
SOCKADDR_IN addrClient;
int len=sizeof(SOCKADDR);
SOCKET sockClient=accept(sockSrv,(SOCKADDR *)&addrClient,&len);
if(sockClient == INVALID_SOCKET){
printf("Invalid client socket!\r\n");
break;
}
//安全属性
SECURITY_ATTRIBUTES sa;
sa.nLength=sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle=TRUE;
sa.lpSecurityDescriptor=NULL;
HANDLE hReadPipe,hWritePipe;
HANDLE hWriteShell,hReadShell;
//创建管道
if(!CreatePipe(&hReadPipe,&hWriteShell,&sa,NULL)){
printf("Create anomyous pipe failed!\r\n");
break;
};
if(!CreatePipe(&hReadShell,&hWritePipe,&sa,NULL)){
printf("Create anomyous pipe failed!\r\n");
break;
};
//设置启动参数并启动shell子进程
STARTUPINFO startupInfo;
ZeroMemory(&startupInfo,sizeof(STARTUPINFO));
startupInfo.cb=sizeof(STARTUPINFO);
startupInfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW;
startupInfo.hStdInput =hReadPipe;
startupInfo.hStdOutput=hWritePipe;
startupInfo.hStdError = hWritePipe;
startupInfo.wShowWindow=SW_SHOW;
PROCESS_INFORMATION pi;
CreateProcess(NULL,"cmd",NULL,NULL,
TRUE,0,NULL,NULL,&startupInfo,&pi);
DWORD threadId1,threadId2;
THREADPARAM tp;
tp.socket=sockClient;
tp.hReadShell=hReadShell;
tp.hWriteShell=hWriteShell;
HANDLE h1=CreateThread(NULL,0,RecvFunc,(LPVOID)&tp,NULL,&threadId1);
HANDLE h2= CreateThread(NULL,0,SendFunc,(LPVOID)&tp,NULL,&threadId2);
//WaitForSingleObject(h1,INFINITE);
//WaitForSingleObject(h2,INFINITE);
}
closesocket(sockSrv);
WSACleanup();
return ;
}
DWORD WINAPI RecvFunc(LPVOID lpParam){
THREADPARAM *pParam=(THREADPARAM *)lpParam;
char buf[4096];
while(1){
if(pParam->socket == INVALID_SOCKET){
return 0;
}
memset(buf,0,4096);
DWORD dwRecvLen=recv(pParam->socket,buf,100,0);
if(dwRecvLen <= 0){
closesocket(pParam->socket);
pParam->socket=INVALID_SOCKET;
return 0;
}
DWORD dwBytesWritten;
WriteFile(pParam->hWriteShell,buf,dwRecvLen,&dwBytesWritten,0);
printf("In RecvFunc:\nsocket=0x%08x\r\n",pParam->socket);
printf("Write %d bytes:%s,%d bytes writen actually\r\n",dwRecvLen,buf,dwBytesWritten);
}
return 0;
}
DWORD WINAPI SendFunc(LPVOID lpParam){
THREADPARAM *pParam=(THREADPARAM *)lpParam;
char buf[4096];
while(1){
if(pParam->socket == INVALID_SOCKET)
return 0;
memset(buf,0,4096);
DWORD dwRead=0;
ReadFile(pParam->hReadShell,buf,100,&dwRead,0);
if(dwRead != 0){
int ret=send(pParam->socket,buf,dwRead+1,0);
printf("In SendFunc:\nsocket=0x%08x\r\n",pParam->socket);
printf("Read %d bytes:%s\r\nSend",dwRead,buf);
}
}
return 0;
}
posted on 2009-09-23 13:48 Joshua Leung 阅读(388) 评论(0) 编辑 收藏 举报