|
C/C++ Миниатюрный сокс-сервер Николай "GorluM" Андреев Xakep, номер #054, стр. 054-088-3 Далее запустим функцию FlushRecvBufferUntil, с помощью которой пропускаем мимо ушей все лишнее, что хочет сообщить нам клиент. И только когда заголовок запроса к прокси полностью принят (пришел '\0'), мы попытаемся сконнектиться с dwDestIp (его получили из запроса). При успешном соединении создаем бесконечный цикл, в котором будем совершать обмен данными в обоих сокетах: полученных accept`ом и connect`ом. С помощью функции select и пары макросов проверим, есть ли данные в сокетах. Для этого сначала создадим переменную типа fd_set, потом макросом FD_ZERO обнулим ее, а FD_SET`ом добавим к ней указатель на сокет, из которого будем читать данные. Теперь, вызвав функцию select и передав во втором параметре нашу переменную, мы можем воспользоваться макросом FD_ISSET. С его помощью мы узнаем состояние очереди чтения. И только когда она не пуста, читаем данные из одного сокета и пишем их в другой. Поскольку мы хотим выполнять эти действия в одном цикле и в одном потоке, нам надо избавиться от одного нежелательного эффекта. Дело в том, что функция recv останавливает нить, из которой запущена, и ждет получения данных. Если в момент такой остановки придут данные в другой сокет, наша программа не сможет их перенаправить, так как будет занята. Как выяснилось, выйти из этого положения довольно просто. Нашим сокетам необходимо сообщить некоторый параметр, заставляющий recv и другие подобные функции выполняться в отдельном потоке. Вот как это выглядит в нашей программе: u_long ulVal = 0; ioctlsocket(s, FIONBIO, &ulVal); Сокеты, не останавливающие нить до конца выполнения той или иной операции, называются неблокирующими. Если соединение рвется или происходит какая-либо ошибка, то цикл завершается, оба сокета закрываются, а нить заканчивает свое существование. Break Вот и все. Как видишь, такая полезная программа очень проста в написании. Осталось только вставить пару строк для уменьшения размера exe'шника. Получившийся прокси прекрасно работает со всеми приложениями, которые я смог найти у себя на винте. ICQ сначала ругалась, но потом я отрубил работу DNS через firewall, и все заработало. Сам проект для Visual Studio .NET и полный исходный текст программы, а также скомпилированный exe’шник ты можешь взять на диске или скачать с сайта www.xakep.ru. Если возникли какие-то вопросы, идеи или замечания - пиши. Постараюсь ответить. Удачного компилирования. |