Exemple #1
0
int main(int argc, char **argv) {

   char c='\0';
   sd.host = "lvr-itach"; sd.port=4998; 
   sd.description = "itach"; sd.exit = TRUE;
    
   initWinsock();
   initClientThread(&sd);
   menu();
   tty_buffering(FALSE);

   while (c!='q') {
   
      c=getChar();
      
      switch (c) {
         case 'i':
            ++mode %= REMOTE_MODES;
            printf("\rmode: %s\n", szMode[mode]);    
            break;
         case '\n':
            break;
         case 'q':
            tty_buffering(TRUE);
            printf("\rExiting...\n");
            rxClientThreadExit(&sd);
            while(areSocketThreadsRunning())
               Sleep(500); 
            WSACleanup();
            break;
         default:
            sendMsg(getIrTx(c));   
      }
   }    
}
    bool init(RcfConfigT *)
    {
        Lock lock(getRootMutex());
        if (gInitRefCount == 0)
        {

            gpGlobals = new Globals();

            // General initialization.
            
            RCF::getCurrentTimeMs();
            initAmiHandlerCache();
            initLogManager();
            initAmi();
            initObjectPool();
            initPerformanceData();
            initThreadLocalData();
            initTpHandlerCache();


#if RCF_FEATURE_FILETRANSFER==1
            initFileIoThreadPool();
#endif


#if RCF_FEATURE_SF==1
            initRegistrySingleton();
#endif


#ifdef BOOST_WINDOWS
            initWinsock();
            initPfnGetUserName();
#endif


#ifndef BOOST_WINDOWS
            // Disable broken pipe signals on non-Windows platforms.
            std::signal(SIGPIPE, SIG_IGN);
#endif


#if RCF_FEATURE_SSPI==1
            SspiInitialize();
#endif

           
#if RCF_FEATURE_SERVER==1
            // Start the AMI thread pool.
            gpAmiThreadPool = new AmiThreadPool(); 
            gpAmiThreadPool->start();
#endif

        }

        ++gInitRefCount;
        return gInitRefCount == 1;
    }
    bool init(RcfConfigT *)
    {
        Lock lock(getRootMutex());
        if (gInitRefCount == 0)
        {

            gpGlobals = new Globals();

            // General initialization.

            RCF::getCurrentTimeMs();
            initAmiHandlerCache();
            IdentityFilter::spFilterDescription = new FilterDescription("identity filter", RcfFilter_Identity, true);
            XorFilter::spFilterDescription = new FilterDescription("Xor filter", RcfFilter_Xor, true);
            initFileIoThreadPool();
            initAmi();
            
            #if defined(BOOST_WINDOWS)
            initNamedPipeEndpointSerialization();
            #endif

            initObjectPool();
            initPerformanceData();
            

            //#if defined(sun) || defined(__sun) || defined(__sun__)
            //if (!pThreadLocalDataPtr) pThreadLocalDataPtr = new ThreadLocalDataPtr;
            //#endif

            initThreadLocalData();
            initTpHandlerCache();

            #ifdef RCF_USE_OPENSSL
            //initOpenSsl();
            initOpenSslEncryptionFilterDescription();
            #endif

            #ifdef RCF_USE_ZLIB
            initZlibCompressionFilterDescriptions();
            #endif

            initLogManager();

            #ifdef RCF_USE_SF_SERIALIZATION
            initRegistrySingleton();
            initTcpEndpointSerialization();
            initUdpEndpointSerialization();
            
            #if defined(BOOST_WINDOWS)
            initWin32NamedPipeEndpointSerialization();            
            #endif

            #ifdef RCF_HAS_LOCAL_SOCKETS
            initUnixLocalEndpointSerialization();
            #endif

            #endif // RCF_USE_SF_SERIALIZATION


            #ifdef BOOST_WINDOWS
            initWinsock();
            initPfnGetUserName();
            SspiInitialize();
            #endif

#ifndef BOOST_WINDOWS
            // Disable broken pipe signals.
            std::signal(SIGPIPE, SIG_IGN);
#endif
            
            // Start the AMI thread pool.
            gpAmiThreadPool = new AmiThreadPool(); 
            gpAmiThreadPool->start();
        }

        ++gInitRefCount;
        return gInitRefCount == 1;
    }
int main(int argc, char *argv[]) {

	// check argument
	if (argc < 3) {
		// std::cout << "Usage: mc.exe [sync folder path] [refresh interval in ms] [server IP] [server port] [client listen port]" << std::endl;
		std::cout << "Usage: mc.exe [sync folder path] [config file path]" << std::endl;
		exit(EXIT_FAILURE);
	}

	// get argument
	std::string monitorPath(argv[1]);
	// int refreshInterval = atoi(argv[2]);
	// char *serverIP = "127.0.0.1";
	// int serverPort = 4180;
	// int listenPort = 4181;

	// open config file
	std::string line;
	std::ifstream configFile(argv[2]);
	std::getline(configFile, line);
	std::istringstream iss(line);
	iss >> line;
	int refreshInterval = stoi(line);
	iss >> line;
	char serverIP[16];
	strncpy(serverIP, line.c_str(), 16);
	iss >> line;
	int serverPort = stoi(line);
	iss >> line;
	int listenPort = stoi(line);
	configFile.close();

	// constants
	const Protocol protocol = TCP;
	#ifdef WIN32
		WSADATA wsa;
		initWinsock(&wsa);
	#endif

	/*|=======================================================|*/
	/*|            Connect to server and monitor              |*/
	/*|=======================================================|*/
	struct sockaddr_in serverAddress;
	int serverSocket = getConnectSocket(serverIP, serverPort, protocol, &serverAddress);
	// file monitoring thread
	std::thread monitorThread(monitorFile, serverSocket, std::cref(monitorPath), refreshInterval, listenPort);

	/*|=======================================================|*/
	/*|          Listen to GET request from server            |*/
	/*|=======================================================|*/
	struct sockaddr_in listenAddress;
	int listenSocket = getListenSocket(NULL, listenPort, protocol, &listenAddress);
	// accept loop
	acceptLoop(listenSocket, monitorPath, listenPort);
	
	#ifdef WIN32
		WSACleanup();
	#endif

	threadPrint("Client is KO ed...", "");
	return 0;
}
int main(int argc, char* argv[])
{
	HRESULT hr = 0;
	WSADATA wsaData = {0};
	WORD wVer = MAKEWORD(2,2);

	// initialize opencv frame
	_ocvFrame = cvCreateImage(cvSize(PMDNUMCOLS,PMDNUMROWS), 8, 3);
	_ocvFrameStep = _ocvFrame->widthStep / sizeof(unsigned char);

	// Step 1: initialize the socket
	hr = initWinsock(&wsaData, &wVer);
	if(!SUCCEEDED(hr)) return -1;

	char* ip = "127.0.0.1";
	if(argc > 2) ip = argv[1];
	cout << "ip is " << ip << endl;

	cout << "Opening connection to " << ip << " at port 10000" << endl;
	SOCKET hServer  = {0};
	// open a socket 
	// 
	// for the server we do not want to specify a network address 
	// we should always use INADDR_ANY to allow the protocal stack 
	// to assign a local IP address 
	hServer = socket( AF_INET, SOCK_STREAM, IPPROTO_IP );
	if( hServer == INVALID_SOCKET ) { 
		cout << "Invalid socket, failed to create socket" << endl;
		return -1;
	} 
	// name a socket 
	sockaddr_in saServer = {0};
	saServer.sin_family      = PF_INET;    
	saServer.sin_port        = htons( 10000 );       
	saServer.sin_addr.s_addr = inet_addr( ip );
	
	// connect 
	hr = connectSocket( &hServer, &saServer );  
	if(!SUCCEEDED(hr)) return -1;

	cout << "Connected to server" << endl;
	
	// send device info
	memset(_handShake, 0, PMDREQUESTSIZE);
	memset(_toServer.buffer, 0, sizeof(PMDRequest));
	strcpy_s(_handShake, PMDREQUESTSIZE, "device info\n");

	sendData(hServer, _handShake,strlen(_handShake), 0);
	receiveData(hServer, _handShake, BUFSIZE, 0);
	cout << "server reply: " << _handShake;

	// process data 
	strcpy_s(_toServer.buffer,BUFSIZE, "gimme");
	while(true){
		// send 'gimme'
		hr = sendData(hServer, _toServer.buffer, strlen(_toServer.buffer), 0);
		if(!SUCCEEDED(hr)) break;
		// parse and display data
		int numBytesReceived = receiveData(hServer, (char*)&_fromServer, sizeof(PMDData), true);
		if(numBytesReceived <= 0) break;
		int c = cvWaitKey (1);
		if (c == 'q' || c == 'Q' || c == 27) break;

		for (int i = 0; i < 2; i++)
		{
			cout << _fromServer.fingers[i].id << ":" << "(" << _fromServer.fingers[i].x << ", " << _fromServer.fingers[i].y << ", " << _fromServer.fingers[i].z << ")" << endl;
		}
		
		
		if(BIT_DEBUG){
			byte* tmp = (byte*)&_fromServer;
		
			for (int i = 0; i < 3; i++)
			{
				ostringstream oss;
				for(int j = 0; j < 4; j++, tmp++)
				{
					byte b = *tmp;
					for (int k = 0; k < 8; k++)
					{
						unsigned int n = (b & (1 << k)) >> k;
						oss << n;
					}
					oss << " " ;
				}	
				string outs = oss.str();
				reverse(outs.begin(), outs.end());
				cout << "i: " << i << ", bits:" << outs << endl;
			}
		}
		// display the data in an opencv window
		updateFrameWithNewData();
	}

	cvReleaseImage (&_ocvFrame);

	cout << "Closing connection" << endl;
	// shutdown socket 
	hr = shutdown( hServer, SD_BOTH );
	if( hr == SOCKET_ERROR ) { 
		// WSAGetLastError() 
		cout << "Error trying to perform shutdown on socket" << endl;
		return -1;
	} 
	// close server socket 
	hr = closesocket( hServer );
	hServer = 0;
	if( hr == SOCKET_ERROR ) { 
		cout << "Error failed to close socket" << endl;
	} 

	// Release WinSock DLL 
	hr = WSACleanup();
	if( hr == SOCKET_ERROR ) { 
		cout << "Error cleaning up Winsock Library" << endl;
		return -1;
	} 
	cout << "Data sent successfully" << endl;
	return 0;
}
int ServerSocket::startListen()
{
    if (-1 == initWinsock())
    {
        return -1;
    }
    // create an i/o completion port
    completionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
    if (NULL == completionPort)
    {
        Log::e("CreateIoCompletionPort failed. Error: %d", GetLastError());
        return -1;
    }

    // get number of cores of cpu
    SYSTEM_INFO mySysInfo;
    GetSystemInfo(&mySysInfo);

    // create threads to process i/o completion port events
    std::function<int()> eventProc(std::bind(&ServerSocket::processEventThread, this));
    DWORD numThreads = config.numIOCPThreads;
    if (numThreads == 0)
    {
        numThreads = mySysInfo.dwNumberOfProcessors * 2;
    }
    for (DWORD i = 0; i < numThreads; ++i)
    {
        std::thread* th = new std::thread(eventProc);
        eventThreads.push_back(th);
    }

    // create listen socket
    listenSocket = WSASocket(AF_INET, SOCK_STREAM, 0, NULL, 0, WSA_FLAG_OVERLAPPED);
    // bind listen socket to i/o completion port
    CreateIoCompletionPort((HANDLE)listenSocket, completionPort, (ULONG_PTR)0, 0);

    // bind socket
    SOCKADDR_IN srvAddr;
    srvAddr.sin_addr.S_un.S_addr = htonl(INADDR_ANY);
    srvAddr.sin_family = AF_INET;
    srvAddr.sin_port = htons(config.listenPort);
    int result = bind(listenSocket, (SOCKADDR*)&srvAddr, sizeof(SOCKADDR));
    if (SOCKET_ERROR == result)
    {
        Log::e("Bind failed. Error: %d", GetLastError());
        return -1;
    }

    // start listen
    result = listen(listenSocket, NUM_ACCEPTEX);
    if (SOCKET_ERROR == result)
    {
        Log::e("Listen failed. Error: %d", GetLastError());
        return -1;
    }
    Log::i("server is listening port %d, waiting for clients...", config.listenPort);

    //AcceptEx function pointer
    lpfnAcceptEx = NULL;
    //AcceptEx function GUID
    GUID guidAcceptEx = WSAID_ACCEPTEX;
    //get acceptex function pointer
    DWORD dwBytes = 0;
    result = WSAIoctl(listenSocket, SIO_GET_EXTENSION_FUNCTION_POINTER,
                      &guidAcceptEx, sizeof(guidAcceptEx), &lpfnAcceptEx, sizeof(lpfnAcceptEx),
                      &dwBytes, NULL, NULL);
    if (result != 0)
    {
        Log::e("WSAIoctl get AcceptEx function pointer failed... %d", WSAGetLastError());
        return -1;
    }

    //post acceptEx
    for (int i = 0; i < NUM_ACCEPTEX; ++i)
    {
        postAcceptEx();
    }
    return 0;
}	//end of startListen
bool
fgTcpClient(
    const string &      hostname,
    uint16              port,
    const string &      data,
    bool                getResponse,
    string &            response)
{
    initWinsock();

    SOCKET              socketHandle;
    struct addrinfo *   addressInfo;
    socketHandle = INVALID_SOCKET;
    addressInfo = NULL;
    struct addrinfo     hints;
    int                 itmp;

    ZeroMemory(&hints,sizeof(hints));
    hints.ai_family = AF_UNSPEC;
    hints.ai_socktype = SOCK_STREAM;
    hints.ai_protocol = IPPROTO_TCP;

    // Resolve the server address and port.
    itmp = getaddrinfo(
        hostname.c_str(),           // Hostname or IP #
        fgToString(port).c_str(),   // Service name or port #
        &hints,
        &addressInfo);              // RETURNED
    if (itmp != 0)
        return false;               // Server does not appear to exist

    struct addrinfo *ptr = NULL;
    // Attempt to connect to an IP address until one succeeds. It's possible
    // for more than 1 to be returned if there are more than 1 namespace service
    // providers (for instance local hosts file vs. DNS server), according to
    // MS docs:
    for(ptr=addressInfo; ptr != NULL ;ptr=ptr->ai_next) {
        socketHandle =
            socket(
                ptr->ai_family,
                ptr->ai_socktype, 
                ptr->ai_protocol);
        if (socketHandle == INVALID_SOCKET) {
            // Couldn't use scope guard for freeaddrinfo due to compile issues:
            freeaddrinfo(addressInfo);
            FGASSERT_FALSE1(fgToString(WSAGetLastError()));
        }
        // Try to connect to the server
        itmp = connect(
            socketHandle,
            ptr->ai_addr,
            (int)ptr->ai_addrlen);
        if (itmp == 0)
            break;
        else {
            closesocket(socketHandle);
            socketHandle = INVALID_SOCKET;
        }
    }
    freeaddrinfo(addressInfo);
    if (socketHandle == INVALID_SOCKET)
        return false;               // Unable to connect, server not listening ?

    // 'send' will block for buffering since we've created a blocking socket, so the
    // value returned is always either the data size or an error:
    itmp = send(socketHandle,data.data(),int(data.size()),0);
    FGASSERT1(itmp != SOCKET_ERROR,fgToString(WSAGetLastError()));

    // close socket for sending to cause server's recv/read to return a zero
    // size data packet if server is waiting for more (ie to flush the stream).
    itmp = shutdown(socketHandle,SD_SEND);
    FGASSERT1(itmp != SOCKET_ERROR,fgToString(WSAGetLastError()));

    if (getResponse) {
        response.clear();
        do {
            char    buff[1024];
            // If server doesn't respond and closes connection we'll immediately get
            // a value of zero here and nothing will be placed in buff. Otherwise
            // we'll continue to receive data until server closes connection causing
            // the zero message:
            itmp = recv(socketHandle,buff,sizeof(buff),0);
            FGASSERT1(itmp != SOCKET_ERROR,fgToString(WSAGetLastError()));
            if (itmp > 0)
                response += string(buff,itmp);
        }
        while (itmp > 0);
        FGASSERT(itmp == 0);
    }

    // Couldn't use scope guard due to compile issues:
    closesocket(socketHandle);
    return true;
}
void
fgTcpServer(
    uint16      port,
    bool        respond,
    bool(*handler)(const string & ipAddr,const string & dataIn,string & response),
    size_t      maxRecvBytes)
{
    initWinsock();
    SOCKET      sockListen = INVALID_SOCKET;

    // Set up the listening socket:
    struct addrinfo     hints;
    ZeroMemory(&hints,sizeof(hints));
    hints.ai_family = AF_INET;          // IPv4
    hints.ai_socktype = SOCK_STREAM;    // A reliable, 2-way, stream-based connection (requires TCP)
    hints.ai_protocol = IPPROTO_TCP;
    hints.ai_flags = AI_PASSIVE;
    struct addrinfo     *addrInfoPtr = NULL;
    int itmp = getaddrinfo(NULL,fgToString(port).c_str(),&hints,&addrInfoPtr);
    FGASSERT1(itmp == 0,fgToString(itmp));
    sockListen = socket(addrInfoPtr->ai_family,addrInfoPtr->ai_socktype,addrInfoPtr->ai_protocol);
    if (sockListen == INVALID_SOCKET) {
        freeaddrinfo(addrInfoPtr);
        FGASSERT_FALSE1(fgToString(WSAGetLastError()));
    }
    itmp = bind(sockListen,addrInfoPtr->ai_addr,(int)addrInfoPtr->ai_addrlen);
    if (itmp == SOCKET_ERROR) {
        closesocket(sockListen);
        freeaddrinfo(addrInfoPtr);
        FGASSERT_FALSE1(fgToString(WSAGetLastError()));
    }
    itmp = listen(sockListen, SOMAXCONN);
    if (itmp == SOCKET_ERROR) {
        closesocket(sockListen);
        freeaddrinfo(addrInfoPtr);
        FGASSERT_FALSE1(fgToString(WSAGetLastError()));
    }
    freeaddrinfo(addrInfoPtr);

    // Receive messages and respond until finished:
    SOCKET      sockClient;
    bool        handlerRetval = true;
    do {
        fgout << fgnl << "> " << std::flush;
        sockaddr_in     sa;
        sa.sin_family = AF_INET;
        socklen_t       sz = sizeof(sa);
        sockClient = accept(sockListen,(sockaddr*)(&sa),&sz);
        if (sockClient == INVALID_SOCKET) {
            closesocket(sockListen);
            FGASSERT_FALSE1(fgToString(WSAGetLastError()));
        }
        char * clientStringPtr = inet_ntoa(sa.sin_addr);
            FGASSERT(clientStringPtr != NULL);
        string     ipAddr = string(clientStringPtr);
        //fgout << "receiving from " << ipAddr << " ... " << std::flush;
        string     dataBuff;
        int itmp = 0;
        do {
            char    recvbuf[1024];
            // recv() will return when either it has filled the buffer, copied over everthing
            // from the socket input buffer (only if non-empty), or when the the read connection
            // is closed by the client. Otherwise it will block (ie if input buffer empty):
            itmp = recv(sockClient,recvbuf,sizeof(recvbuf),0);
            fgout << "." << std::flush;
            if (itmp > 0)
                dataBuff += string(recvbuf,itmp);
        }
        while ((itmp > 0) && (dataBuff.size() <= maxRecvBytes));
        if (itmp != 0) {
            closesocket(sockClient);
            if (itmp < 0)
                fgout << "TCP RECV ERROR: " << itmp;
            else if (itmp > 0)
                fgout << " OVERSIZE MESSAGE IGNORED.";
            fgout << std::flush;
            continue;
        }
        fgout << ": " << std::flush;
        if (!respond)   // Avoid timeout errors on the data socket for long handlers that don't respond:
            closesocket(sockClient);
        string     response;
        try {
            handlerRetval = handler(ipAddr,dataBuff,response);
        }
        catch(FgException const & e) {
            fgout << "Handler exception (FG4 exception): " << e.no_tr_message();
        }
        catch(std::exception const & e) {
            fgout << "Handler exception (std::exception): " << e.what();
        }
        catch(...) {
            fgout << "Handler exception (unknown type)";
        }
        if (respond) {
            if (!response.empty()) {
                int     bytesSent = send(sockClient,response.data(),int(response.size()),0);
                shutdown(sockClient,SD_SEND);
                if (bytesSent != int(response.size()))
                    fgout << "TCP SEND ERROR: " << bytesSent << " (of " << response.size() << ").";
            }
            closesocket(sockClient);
        }
        fgout << std::flush;
    } while (handlerRetval == true);
    closesocket(sockListen);
}