Многонитевой portmapper
От: Д.С.  
Дата: 23.07.03 06:20
Оценка:
есть следующий исходный текст. не работает хоть убейся веником. т.е. работает, но неправильно. он должен (как) задумывалось перемэпить порт одного компутэра на порт другого. перемэпивает, но только как-то косо, муть какая-то приходит. в чем проблема в силу своей неособой грамотности понять не могу. где ошибка ? или этот весь текст сплошная ошибка ? где искать ?


#include <windows.h>
#include <winsock.h>

#define SERVER_PORT 80
#define SERVER_HOST INADDR_ANY
#define TARGET_PORT 80
#define TARGET_HOST "proxy"
#define MAX_SERVER_CONNECTIONS 16
#define BUFFER_SIZE 16384
#define STACK_SIZE 32768

#define SERVER_DEVELOPMENT

#define CLIENT *((SOCKET *)lpParameter)
DWORD WINAPI ThreadProcedure (LPVOID lpParameter) {
    SOCKET target_socket;
    sockaddr_in addr;
    hostent *target_host;

    if (target_host=gethostbyname(TARGET_HOST)) {
        addr.sin_addr.S_un.S_addr = *(DWORD* ) target_host->h_addr_list[0];
        target_socket=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(target_socket!=INVALID_SOCKET) {
            addr.sin_family = AF_INET;
            addr.sin_port = htons (TARGET_PORT);
            if(connect(target_socket,(sockaddr *)&addr,sizeof(addr))!=SOCKET_ERROR) {
                char buffer[BUFFER_SIZE];
                int buffer_length=0;
                while (TRUE) {
                    buffer_length=recv(CLIENT,buffer,BUFFER_SIZE,NULL);
                    send(target_socket,buffer,buffer_length,NULL);
                    buffer_length=recv(target_socket,buffer,BUFFER_SIZE,NULL);
                    send(CLIENT,buffer,buffer_length,NULL);
                    }
                }
            #ifdef SERVER_DEVELOPMENT
            else MessageBox(0,"Connect()","Ошибка",MB_ICONSTOP);
            #endif
            }
        #ifdef SERVER_DEVELOPMENT
        else MessageBox(0,"Socket()","Ошибка",MB_ICONSTOP);
        #endif
        closesocket(target_socket);
        }
    #ifdef SERVER_DEVELOPMENT
    else MessageBox(0,"GetHostByName()","Ошибка",MB_ICONSTOP);
    #endif
    closesocket(CLIENT);
    ExitThread(0);
    
    return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR pCmdLine,int nCmdShow) {

    WSADATA wsdata;
    if (WSAStartup(MAKEWORD(2,0),&wsdata)!=SOCKET_ERROR) {
        SOCKET in;
        in=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(in!=INVALID_SOCKET) {
            sockaddr_in addr_in;
            addr_in.sin_family=AF_INET;
            addr_in.sin_addr.S_un.S_addr=htonl(SERVER_HOST);
            addr_in.sin_port=htons (SERVER_PORT);
            if(bind(in,(sockaddr*)&addr_in,sizeof(addr_in))!=SOCKET_ERROR) {
                if(listen(in,MAX_SERVER_CONNECTIONS)!=SOCKET_ERROR) {
                    SOCKET out;
                    while(TRUE)    {
                        out=accept(in,NULL,NULL);
                        if (out) CreateThread(NULL,STACK_SIZE,ThreadProcedure,&out,NULL,NULL);
                        }
                    }
                #ifdef SERVER_DEVELOPMENT
                else MessageBox(0,"Listen()","Ошибка",MB_ICONSTOP);
                #endif
                }
            #ifdef SERVER_DEVELOPMENT
            else MessageBox(0,"Bind()","Ошибка",MB_ICONSTOP);
            #endif
            closesocket(in);
            }
        #ifdef SERVER_DEVELOPMENT
        else MessageBox(0,"Socket()","Ошибка",MB_ICONSTOP);
        #endif
        WSACleanup();    
        }
    #ifdef SERVER_DEVELOPMENT
    else MessageBox(0,"WSAStartup()","Ошибка",MB_ICONSTOP);
    #endif

    return 0;
}

// else MessageBox(0,"Егог","Ошибка",MB_ICONSTOP);


заранее благодарен ...
Re: Многонитевой portmapper
От: Vamp Россия  
Дата: 23.07.03 10:49
Оценка: 3 (1)
Предполагаю ошибки и ряд некорректностей:



...
#define CLIENT *((SOCKET *)lpParameter) // Некор. 1. Так делать - дурной тон.
...

DWORD WINAPI ThreadProcedure (LPVOID lpParameter) {
    SOCKET target_socket;
    sockaddr_in addr;
    hostent *target_host;

...
                char buffer[BUFFER_SIZE];
                int buffer_length=0;
                while (TRUE) {
                    buffer_length=recv(CLIENT,buffer,BUFFER_SIZE,NULL);
                    send(target_socket,buffer,buffer_length,NULL);
                    buffer_length=recv(target_socket,buffer,BUFFER_SIZE,NULL); //****
                    send(CLIENT,buffer,buffer_length,NULL);
                    }
                }
/*Некор. 2. Не вижу выхода из цикла
  Ошибка 1. Зря считаешь в строке ***, что сервер готов отвечать. Ты ему вполне мог отправить 1 байт, принятый первым recv(). Сервер ждет продолжения... Тут нужны select().
*/
            #ifdef SERVER_DEVELOPMENT
            else MessageBox(0,"Connect()","Ошибка",MB_ICONSTOP);
            #endif
//Некорр. 3. В высшей степени плохой стиль.
...
        closesocket(target_socket); // Обрати внимание - здесь мы никогда не окажемся...
    ExitThread(0); // Некорр. 4. Не надо. См. Некорр. 5
    
    return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR pCmdLine,int nCmdShow) {
...
                    SOCKET out;
                    while(TRUE)    {
                        out=accept(in,NULL,NULL);
                        if (out) CreateThread(NULL,STACK_SIZE,ThreadProcedure,&out,NULL,NULL);
/*Некорр. 5. Потоки в C/C++ создаются с помощью [msdn]_beginthreadex[/msdn]!
  Ошибка 2.  Ты передаешь адрес сокета. В следующей итерации по этому адресу будет другое значение и предыдущая нить вполне может им воспользоваться.
*/
...


По-моему, так.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: Многонитевой portmapper
От: Д.С.  
Дата: 24.07.03 07:54
Оценка:
Огромное спасибо за ответ !
Даже не ожидал такого полного пояснения ...
Я конечно понимаю, что спасибо в карман не положишь, на стол не поставишь ...
Но пока могу только сказать еще раз спасибо !
Re[3]: Многонитевой portmapper
От: Аноним  
Дата: 24.07.03 08:19
Оценка:
Вот новые исходники, переписанные по-новой. Всё равно не работает хоть ты пасатижами застрелись ... вроде всё поправил, тем не менее ... в чем теперь дело ?

да, в теле главной нити есть вечный цикл. вообще программа предназначена для вечной работы в фоновом режиме. для того, чтобы из нее выходить надо родить окно, ловить кучу сообщений для этого окна и т.д. оно надо (хотя бы на текущий момент, когда сама "рабочая часть" не работает) ?


#include <windows.h>
#include <winsock.h>

#define SERVER_HOST INADDR_ANY
#define SERVER_PORT 80
#define TARGET_HOST "proxy.kes"
#define TARGET_PORT 80
#define MAX_SERVER_CONNECTIONS 16
#define BUFFER_SIZE 16384

struct connection_data {
    SOCKET server;
    SOCKET target;
    bool connection;
};

DWORD WINAPI ToTarget (LPVOID lpParameter) {
    char buffer[BUFFER_SIZE];
    int to_target;
    do {
        to_target=recv((*((connection_data *)lpParameter)).server,buffer,BUFFER_SIZE,NULL);
        if (to_target) send((*((connection_data *)lpParameter)).target,buffer,to_target,NULL);
        else (*((connection_data *)lpParameter)).connection=FALSE;
    } while ((*((connection_data *)lpParameter)).connection==TRUE);
    closesocket((*((connection_data *)lpParameter)).server);
    ExitThread(0);
    return 0;
}

DWORD WINAPI ToServer (LPVOID lpParameter) {
    char buffer[BUFFER_SIZE];
    int to_server;
    do {
        to_server=recv((*((connection_data *)lpParameter)).target,buffer,BUFFER_SIZE,NULL);
        if (to_server) send((*((connection_data *)lpParameter)).server,buffer,to_server,NULL);
        else (*((connection_data *)lpParameter)).connection=FALSE;
    } while ((*((connection_data *)lpParameter)).connection==TRUE);
    closesocket((*((connection_data *)lpParameter)).target);
    ExitThread(0);
    return 0;
}

DWORD WINAPI ThreadProcedure (LPVOID lpParameter) {
    connection_data connection;
    connection.server=*((SOCKET *)lpParameter);
    sockaddr_in addr;
    hostent *host;

    if (host=gethostbyname(TARGET_HOST)) {
        addr.sin_addr.S_un.S_addr = *(DWORD* ) host->h_addr_list[0];
        connection.target=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(connection.target!=INVALID_SOCKET) {
            addr.sin_family = AF_INET;
            addr.sin_port = htons (TARGET_PORT);
            if(connect(connection.target,(sockaddr *)&addr,sizeof(addr))!=SOCKET_ERROR) {
                connection.connection=TRUE;
                CreateThread(NULL,NULL,ToServer,&connection,NULL,NULL);
                CreateThread(NULL,NULL,ToServer,&connection,NULL,NULL);
                while(connection.connection==TRUE) { }
                }
            }
        }

    ExitThread(0);
    return 0;
}

int APIENTRY WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR pCmdLine,int nCmdShow) {

    WSADATA wsdata;
    if (WSAStartup(MAKEWORD(2,0),&wsdata)!=SOCKET_ERROR) {
        SOCKET in;
        in=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
        if(in!=INVALID_SOCKET) {
            sockaddr_in addr_in;
            addr_in.sin_family=AF_INET;
            addr_in.sin_addr.S_un.S_addr=htonl(SERVER_HOST);
            addr_in.sin_port=htons (SERVER_PORT);
            if(bind(in,(sockaddr*)&addr_in,sizeof(addr_in))!=SOCKET_ERROR) {
                if(listen(in,MAX_SERVER_CONNECTIONS)!=SOCKET_ERROR) {
                    SOCKET out;
                    while (TRUE) {
                        if(out=accept(in,NULL,NULL)) {
                            CreateThread(NULL,NULL,ThreadProcedure,&out,NULL,NULL);
                            }
                        }
                    }
                }
            closesocket(in);
            }
        WSACleanup();    
        }

    return 0;
}
Re[3]: Многонитевой portmapper
От: Valerio Россия linkedin.com/in/boronin
Дата: 25.07.03 03:56
Оценка:
Здравствуйте, Д.С., Вы писали:

ДС>Огромное спасибо за ответ !

ДС>Даже не ожидал такого полного пояснения ...
ДС>Я конечно понимаю, что спасибо в карман не положишь, на стол не поставишь ...
ДС>Но пока могу только сказать еще раз спасибо !
лучше поставь оценку, а то и правда ни на стол, ни в карман...
... << RSDN@Home 1.1 beta 1 >>
Valery A. Boronin, RSDN Team, linkedin.com\in\boronin
R&D Mgmt & Security. AppSec & SDL. Data Protection and Systems Programming. FDE, DLP, Incident Management. Windows Filesystems and Drivers.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.