Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > C/C++ Сетевое программирование
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 17.04.2012, 23:29   #1
Gwynbleidd
 
Регистрация: 16.12.2007
Сообщений: 8
По умолчанию Прокси-сервер

Добрый вечер

Возникли проблемы про написании прокси-сервера на Си.
Сайты типа www.ya.ru грузятся без проблем. А вот когда перехожу на www.rambler.ru или www.yandex.ru, то возникают проблемы.

1. Происходит загрузка, и в определённый момент программа вылеает - не смог понять в чём дело, но видно в переполнении буфера или ещё в чём-то. Как можно исправить это?
Когда запускаешь в отладчике, то он указывает на ассемб. код функции strcat и пишет про Нарушение прав доступа при записи.

2. Во время работы программы когда загружается сайт, то ноутбук начинает издавать пищание системным динакомиком - около 3-4 писков, иногда больше. С чем это может быть связано?

Заранее спасибо

Вот код программы, доп. функции в виде разбора запроса и прочего не стал вставлять, там достаточно просто всё.
Gwynbleidd вне форума Ответить с цитированием
Старый 17.04.2012, 23:31   #2
Gwynbleidd
 
Регистрация: 16.12.2007
Сообщений: 8
По умолчанию

Код:
// Подключаем необходимые библиотеки
#include "stdafx.h"
#include <winsock2.h>
#include <windows.h>
#include <process.h>
#include <stdio.h>
#include <string.h>
#include <iostream>
#pragma comment (lib, "ws2_32.lib")
// Определяем параметры прокси: порт и ip-адрес
#define PROXY_PORT 7777 // порт прокси
#define PROXY_IP "192.168.126.10" // ip-адрес прокси-сервера
struct Request_key
{
        char User_Agent_k [16]; 
        char Host_k [6]; 
        char Accept_k [10]; 
        char Referer_k [10]; 
        char Accept_Language_k [50]; 
        char Accept_Encoding_k [50]; 
        char Accept_Charset_k [50]; 
        char Cookie_k [10]; 
        char Pragma_k [10];
        char Cache_Control_k [50];
        char Сonnection_k [15];
};
struct Request_value
{
        char Command_v [10]; 
        char URL_v [256]; 
        char Protocol_v [10]; 
        char User_Agent_v [256]; 
        char Host_v [20]; 
        char Accept_v [1024]; 
        char Referer_v [256]; 
        char Accept_Language_v [50]; 
        char Accept_Encoding_v [50]; 
        char Accept_Charset_v [50]; 
        char Cookie_v [4096]; 
        char Pragma_v [20];
        char Cache_Control_v [20];
        char Сonnection_v [20];
        char Host_name [256];
};
int Recv(int unsigned clientsocket, char *recvbuf, int size, int time) //приём данных с помощью select
{
    timeval tm = {0, time}; //задержка, задаётся параметром time
    fd_set fd; //
    FD_ZERO(&fd); //
    FD_SET(clientsocket, &fd); //
    int rc = select(0, &fd, NULL, NULL, &tm); 
//определяет состояние сокетов. 0 - ничего не делает, 
//&fd - указатель на набор сокетов, которые надо проверить на разрешение на чтение
//&tm - задаёт макс время на ожидание? задаётся в timeval
    if(rc == SOCKET_ERROR)
    {
        GetLastError();
        return -1;
    }
    if(rc)
        return recv(clientsocket, recvbuf, size, 0);
}
int GetAddressAndPort (char *str, char *address) 
{
    
    char *p, buf[256], command[5], protocol [10];
    int i, j;
    sscanf (str, "%s%s%s", command, buf, protocol);
    p=strstr(buf,"http://"); //ищем вхождение http:// в нашем массиве buf. если вхождение нашлось, то в p будет указатель на это вхождение.
    //HTTP
    if(p) // если в p не ноль, т.е. в нашем массиве buf всё таки было вхождение http://
    {
        p+=strlen("http://"); //прибавляем к указателю р длину 'http://'
        for(i=0;i<strlen(p);i++) //
            if( *(p+i)=='/') break; //получаем адрес хоста, к которому обращается клиент
        char c = *(p+i);
        *(p+i)=0;
        strcpy(address,p);
        *(p+i) = c;//копируем в переменную address наш указатель p, т.е. как раз адрес сервера
              //default http port 
    } 
        
    return 1;
}

Последний раз редактировалось rpy3uH; 18.04.2012 в 00:00.
Gwynbleidd вне форума Ответить с цитированием
Старый 17.04.2012, 23:34   #3
Gwynbleidd
 
Регистрация: 16.12.2007
Сообщений: 8
По умолчанию

Код:
UINT WINAPI Proxy (LPVOID clientsocket)
{
    char recvbuf [10240];
    struct in_addr host2_addr;
    struct sockaddr_in host_addr;
    struct hostent *ht;
    int retval;
    SOCKET hostsocket;
    char *host_name;
    struct Request_value Request_v;
    struct Request_key Request_k;
    struct Request_value Request_m;
    int i = 0;
    char recvbuf2 = NULL;
    hostsocket = socket (AF_INET, SOCK_STREAM, 0);
    if (hostsocket == INVALID_SOCKET)
    {
        printf ("\n Error in New a Socket.");
        WSACleanup();
        return -2;
    }
    
    ZeroMemory (&host2_addr, sizeof(host2_addr));
    ZeroMemory (&Request_v, sizeof(Request_v));
    ZeroMemory (&Request_k, sizeof(Request_k));
    ZeroMemory (&Request_m, sizeof(Request_m));
    ZeroMemory (recvbuf, sizeof(recvbuf));
    
    retval = recv ((SOCKET)clientsocket, recvbuf, sizeof(recvbuf), 0);
    printf("\n Received %d bytes,data\n[%s]\nfrom client\n\n",retval,recvbuf);
    
    GetAddressAndPort (recvbuf, Request_v.Host_name);
    
    ParserRequest (recvbuf, &Request_k, &Request_v);
    strcpy(Request_m .Сonnection_v, " Close");
    printf ("\nЗАПРОС:\n%s", ss);
    ZeroMemory(&host_name, sizeof(host_name));
    ZeroMemory(&ht, sizeof(ht));
    
    host_name = Request_v.Host_name;
    ht = gethostbyname(host_name);
    //while (ht->h_addr_list[i] != 0)
         host2_addr.s_addr = *(u_long *)ht->h_addr_list[0];
    
    ZeroMemory(&host_addr, sizeof(host_addr));
    host_addr.sin_family = AF_INET; 
    host_addr.sin_addr.s_addr = host2_addr.s_addr; 
    host_addr.sin_port = htons(80);
    if (connect(hostsocket, (struct sockaddr *)&host_addr, sizeof(host_addr)) == SOCKET_ERROR) 
    {
        printf ("Connect () Error: %d\n", WSAGetLastError());
        return -1;
    }
 
    int retval2;
    retval2 = send(hostsocket, ss, strlen(ss), 0); 
    if(retval2 == SOCKET_ERROR)
    {
        printf ("send () Error: %d\n", WSAGetLastError());
        closesocket (hostsocket);
    }
    printf ("Послали хосту %d bytes от клиента\n", retval2);
    
    i = 0;
    int j = 0;
    char recvbuf3 [10240];
    ZeroMemory (recvbuf, sizeof(recvbuf));
    
    while ((retval = Recv((SOCKET)hostsocket, recvbuf, sizeof(recvbuf), 1000000)) != 0) 
    {
      send ((SOCKET)clientsocket, recvbuf, retval, 0);
                    
    }
    
    printf("\n Received %d bytes,data\n[%s]\nfrom server\n", i, recvbuf);
    closesocket (hostsocket);
   
    retval2 = send ((SOCKET)clientsocket, recvbuf, i, 0);
    if (retval2 == SOCKET_ERROR)
    {
        printf ("send () Error: %d\n", WSAGetLastError());
        closesocket ((SOCKET)clientsocket);
    }
        
    printf ("Послали клиенту %d bytes от хоста\n", retval2);
    //}
     
    closesocket((SOCKET)clientsocket);
    printf ("Закрыли соединение с клиентом\n");
    return 0;
}
int main ()
{
    setlocale (LC_ALL, "Russian");
    WSADATA wsd;
    SOCKET listensocket, clientsocket;
    struct sockaddr_in server_addr, client_addr;
    struct hostent *client;
    UINT IDThread;
    HANDLE proxy_Thread;
    printf ("Прокси-сервер\nIP: %s\nPort: %d\n",PROXY_IP, PROXY_PORT);
    if(WSAStartup (0x101, &wsd) != 0) 
    {
        printf ("\n Error in Startup session.\n");
        WSACleanup();
        return -1;
    } 
   
    server_addr.sin_family = AF_INET;
    server_addr.sin_addr.s_addr = INADDR_ANY; 
    server_addr.sin_port = htons(PROXY_PORT); 
    listensocket = socket(AF_INET, SOCK_STREAM, 0); 
    if (listensocket == INVALID_SOCKET)
    {
        printf ("\n Error in New a Socket.");
        WSACleanup();
        return -2;
    }
    
   
        
    if (bind(listensocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) 
    {
        printf ("\n Error in Binding socket.");
        WSACleanup();
        return -3;
    }
    
  
    if (listen (listensocket, 5) != 0) 
    {
        printf ("\n Error in Listen.");
        WSACleanup ();
        return -4;
    }
    
    int size_of_cli = sizeof(client_addr); 
    while (1)
    {
        clientsocket = accept (listensocket, (struct sockaddr *)&client_addr, &size_of_cli);
        if (clientsocket == INVALID_SOCKET)
        {
            printf ("\nError in Accept");
            WSACleanup();
            return -5;
        }
        else
        {
            printf ("Приняли соединение от клиента\n");
            client = gethostbyaddr ((char *)&client_addr.sin_addr.s_addr, 4, AF_INET);
            proxy_Thread = (HANDLE)_beginthreadex (
                NULL,
                0,
                Proxy,
                (LPVOID) clientsocket,
                NULL,
                &IDThread);
            printf ("Запущен поток для обработка клиента с ID: %d\n", IDThread);
        }
        Sleep (100);
    }
        
    return 1;
                    
}
Gwynbleidd вне форума Ответить с цитированием
Старый 15.05.2012, 15:36   #4
BadAndy
Новичок
Джуниор
 
Регистрация: 15.05.2012
Сообщений: 1
По умолчанию

Привет, как-то тихо здесь...
Используй strncat вместо strcat.
Похоже у тебя переполнение буфера. Не лишне добавить контроль.
BadAndy вне форума Ответить с цитированием
Старый 16.05.2012, 08:28   #5
Rock-n-Rolla
Форумчанин
 
Регистрация: 11.01.2012
Сообщений: 177
По умолчанию

Gwynbleidd, открой для себя отладчик и окно "call stack". забудешь про многие проблемы типа выхода за пределы буфера и нарушения доступа к памяти
progromore.i2p - первый русскоязычный портал программистов в скрытосети
Rock-n-Rolla вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Домашний прокси сервер lawliet93 Свободное общение 14 18.04.2012 20:29
Прокси-сервер Kasper1 Свободное общение 1 22.03.2011 01:37
Прокси сервер X-954377 Общие вопросы C/C++ 2 28.06.2010 11:58
Прокси сервер stenl1 Операционные системы общие вопросы 0 05.06.2010 13:12
Прокси сервер AlexDn Безопасность, Шифрование 1 08.01.2010 07:24