Новичок
Профиль
Группа: Участник
Сообщений: 19
Регистрация: 25.3.2008
Репутация: нет Всего: нет
|
Переписал частично код, старые проблемы ушли, появились новые (( С некоторыми сайтами, с тем же www.ya.ru, работает нормально. На всех остальных же выскакивает ошибка "Необработанное исключение в "0x775c15de" в "Proxy.exe": 0xC0000005: Access violation." вот в этом месте: | Код | while ((retval = Recv((SOCKET)hostsocket, &recvbuf2, sizeof(recvbuf2), 1000000)) != 0) // Принимаем ответ хоста на посланный запрос { recvbuf[i] = recvbuf2; ++i; }
|
Правильно ли я понимаю, что ошибка связана с тем, что разные потоки пытаются одновременно работать с recvbuf и recvbuf2? Как можно исправить её? Код программы: | Код | // Подключаем необходимые библиотеки #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; }
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; }
printf ("Создан сокет для подключения к хосту\n");
//while (1) // {
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"); 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; }
printf ("Установили подключение с хостом\n"); 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, &recvbuf2, sizeof(recvbuf2), 1000000)) != 0) // Принимаем ответ хоста на посланный запрос { recvbuf[i] = recvbuf2; ++i; } printf ("Получили ответ хоста на запрос\n"); printf("\n Received %d bytes,data\n[%s]\nfrom server\n", i, recvbuf);
closesocket (hostsocket);
printf ("Закрыли соединение с хостом\n");
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; }
printf ("Библиотека проинициализирована\n");
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; } printf ("Создан слушающий сокет\n"); if (bind(listensocket, (struct sockaddr *)&server_addr, sizeof(server_addr)) != 0) { printf ("\n Error in Binding socket."); WSACleanup(); return -3; } printf ("Запущено пассивное ожидание подключения\n");
if (listen (listensocket, 5) != 0) { printf ("\n Error in Listen."); WSACleanup (); return -4; }
printf ("Запущено прослушивание сети, максимум 5 подключений\n");
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; }
|
Дополнительные фцнкции по разбору запроса и созданию нового не стал включать, там всё просто
|