본문으로 바로가기

출처: http://stackoverflow.com/questions/4993119/redirect-io-of-process-to-windows-socket

 

그니까.. 프로세스의 IO를 소켓으로 redirect 시켜주는 좋은 예제.

서버쪽에서는..

#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdio.h>
 
#pragma comment(lib, "Ws2_32.lib")
 
#define DEFAULT_PORT "27015"
#define DEFAULT_BUFLEN 512
 
int _tmain(int argc, _TCHAR* argv[])
{
 
        WSADATA wsaData;
        int iResult;
 
        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 
        struct addrinfo *result = NULL, *ptr = NULL, hints;
 
        ZeroMemory(&hints, sizeof (hints));
        hints.ai_family = AF_INET;
        hints.ai_socktype = SOCK_STREAM;
        hints.ai_protocol = IPPROTO_TCP;
        hints.ai_flags = AI_PASSIVE;
 
        // Resolve the local address and port to be used by the server
        iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
 
        SOCKET ListenSocket = INVALID_SOCKET;
 
        ListenSocket = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
 
         // Setup the TCP listening socket
        iResult = bind( ListenSocket, result->ai_addr, (int)result->ai_addrlen);
 
        freeaddrinfo(result);
 
        if ( listen( ListenSocket, SOMAXCONN ) == SOCKET_ERROR ) {
            printf( "Listen failed with error: %ld\n", WSAGetLastError() );
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
 
        SOCKET ClientSocket;
 
        ClientSocket = INVALID_SOCKET;
 
        // Accept a client socket
        ClientSocket = accept(ListenSocket, NULL, NULL);
        if (ClientSocket == INVALID_SOCKET) {
            printf("accept failed: %d\n", WSAGetLastError());
            closesocket(ListenSocket);
            WSACleanup();
            return 1;
        }
 
        STARTUPINFO si;
        memset( &si, 0, sizeof( si ) );
        si.cb = sizeof( si );
        si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
        si.wShowWindow = SW_HIDE;
 
        si.hStdInput = (HANDLE)ClientSocket;
        si.hStdOutput = (HANDLE)ClientSocket;
        si.hStdError = (HANDLE)ClientSocket;
 
        PROCESS_INFORMATION pi;
 
        TCHAR cmd[] = TEXT("C:\\Users\\dell\\Desktop\\hello.exe");
 
        if (CreateProcess(NULL, cmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi)) {
            printf("create process successfully\n");
            DWORD i = WaitForSingleObject( pi.hProcess, INFINITE );
            printf("%8x\n", i);
        }
 
 
        CloseHandle( pi.hProcess );
        CloseHandle( pi.hThread );
        closesocket( ClientSocket );
        WSACleanup();
 
}

클라이언트 쪽에서는…

#define WIN32_LEAN_AND_MEAN
 
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
 
 
// Need to link with Ws2_32.lib, Mswsock.lib, and Advapi32.lib
#pragma comment (lib, "Ws2_32.lib")
#pragma comment (lib, "Mswsock.lib")
#pragma comment (lib, "AdvApi32.lib")
 
 
#define DEFAULT_BUFLEN 512
#define DEFAULT_PORT "27015"
 
 
int _tmain(int argc, _TCHAR* argv[])
{
        WSADATA wsaData;
        SOCKET ConnectSocket = INVALID_SOCKET;
        struct addrinfo *result = NULL,
                        *ptr = NULL,
                        hints;
        char recvbuf[DEFAULT_BUFLEN];
        int iResult;
        int recvbuflen = DEFAULT_BUFLEN;
 
        // Initialize Winsock
        iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
 
        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
        iResult = getaddrinfo("localhost", DEFAULT_PORT, &hints, &result);
 
        // Attempt to connect to an address until one succeeds
        for(ptr=result; ptr != NULL ;ptr=ptr->ai_next) {
            // Create a SOCKET for connecting to server
            ConnectSocket = socket(ptr->ai_family, ptr->ai_socktype,
                ptr->ai_protocol);
            if (ConnectSocket == INVALID_SOCKET) {
                printf("socket failed with error: %ld\n", WSAGetLastError());
                WSACleanup();
                return 1;
            }
 
            // Connect to server.
            iResult = connect( ConnectSocket, ptr->ai_addr, (int)ptr->ai_addrlen);
            if (iResult == SOCKET_ERROR) {
                closesocket(ConnectSocket);
                ConnectSocket = INVALID_SOCKET;
                continue;
            }
            break;
        }
 
        freeaddrinfo(result);
 
        if (ConnectSocket == INVALID_SOCKET) {
            printf("Unable to connect to server!\n");
            WSACleanup();
            return 1;
        }
 
        // Receive until the peer closes the connection
        do {
 
            iResult = recv(ConnectSocket, recvbuf, recvbuflen, 0);
            if ( iResult > 0 )
                printf("Bytes received: %d\n", iResult);
            else if ( iResult == 0 )
                printf("Connection closed\n");
            else
                printf("recv failed with error: %d\n", WSAGetLastError());
 
        } while( iResult > 0 );
 
        // cleanup
        closesocket(ConnectSocket);
        WSACleanup();
 
        return 0;
}

외부 프로그램 hello.cpp 에서는..

int _tmain(int argc, _TCHAR* argv[])
{
    printf("hello world!\n");      
    return 0;
}