Ниже написана процедура обработки socks5 сервером подключений. Но она не работает. Проблема, видимо, в цикле ...while(!error)..., хотя для socks4 один в один работает. Пересмотрел много сорцов, разницы вроде нет. Пробую подключаться через Miranda, сервер коннектится к серверу ICQ, но с мирандой они не обмениваются данными. Code: del
мдауж жестоко ты сделал. 1) Если нравится многопоточность, то лучше бы сделал в одной функции цикл обработки коннектов и запуска потока обработки каждого клиента. т.е. создание нового потока с указанием в параметрах - сокета. пашет отлично такая комбинация. 2) Когда считываешь параметры авторизации, то лучше смотреть что предлагает клиент. бывают случае когда клиент говорит что хотю подключиться тока с авторизацией, а ты ему в ответ гворишь всегда - подключайся без авторизации. Так что проверяй предложенные методы и отклоняй запрос если нет метода Без авторизации 3) Хоть гдето проверяй что возвращает тебе recv то есть вероятность на долго подвиснуть + таймауты поставь на recv 4) Ты уверен что миранда тебе шлет запрос на коннект по IP а не по домену? Очень часто во всём софте для универсальности и IP и домены шлются в запросах как домены. И там ты уже сам должен определить что это. А еще лучше сделай поддержку типов по IP v4 и по HOST. Потмоу что первый коннект может и пройдет по IP а потом хз что во втором коннекте будет. может и домен. 5) чтото мне кажется select у тебя не правильно используется. Для nix систем там он отличается от виндового использования 6) нафига гонять while(!error) если внутри цикла ты всё равно выходишь каждый раз по break. проще уже написать for (; 7) close(sock_endpoint); shutdown(sock_endpoint,SD_BOTH); Вот тут ты ошибся с последовательностью операций. Странно как это ты не умудрился тут поймать сигнал об ошибочном сокете. 8) Это С а не С++ 9) Почему ты отсылаешь ответный пакет клиенту тока в случае успешности коннекта? ты должен еще и в случае ошибки его отсылать. 10) пакет отклика на запрос коннекта тебе совсем не надо очищать, достаточно просто выставить флаг удачности/ошибочности коннекта, ну и подправить ip и порт который был задействова при удачном коннекте если конечно коннект был удачным
slesh 1) Смысла, честно говоря, не вижу. Тут, если пришёл клиент - рождаем поток, иначе ждём. 2) Ну, у меня вопрос про конкретный случай, Миранда шлёт как надо всё, хотя и проверять не обязательно, клиент не будет подключаться, если выбранный метод не посылал. 3,5) select этим и занимается, что ждёт данных с таймаутом, тестирую под win, Миранды под nix вроде ещё не существует. 4) Да.(в отладчике ж видно, да и галочка "Resolve hostname throuth proxy" не стоит и соединение есть с login.icq.com как говорил уже). 6) Это скопипастил из обработчика socks4, там считал ошибку, можно и заменить 7) Действительно, спасибо. 8) Ну, не суть важно, указал с\с++ 9) Сделаю. 10) Можно и так. Но дело всё таки не в этом всём. Вот процедура для socks4, и работает: Code: del
Я, конечно, дико извиняюсь, но разве отладчики уже отменили? Вряд ли кому-то захочется разбираться в твоем коде (мне не захотелось).
becensed, можно не извиняться. Я уже писал что смотрел отладчиком. Форум это последнее место, куда я обратился. Люди даже не читают, видимо, а мельком просматривают текст. Вот организация передачи данных от клиента к серверу и обратно. Ошибка скорее всего тут, но она не очевидна. Code: FD_ZERO(&fds_zero); FD_SET(sock_endpoint,&fds_zero); FD_SET(sock_client,&fds_zero); while(!error) { length = 0; fds = fds_zero; select(0,&fds,0,0,&time_out5); if(FD_ISSET(sock_client,&fds)) { length = recv(sock_client,Buffer,ARR_SIZE(Buffer),0);if(len gth <= 0) break; length = send(sock_endpoint,Buffer,length,0);if(length <= 0) break; } if(FD_ISSET(sock_endpoint,&fds)) { length = recv(sock_endpoint,Buffer,ARR_SIZE(Buffer),0);if(l ength <= 0) break; length = send(sock_client,Buffer,length,0);if(length <= 0) break; } } Возможно необходимо реализовать это абсолютно по-другому.
Этото код ты запускаешь на никсе или на винде? И причем тут селек и проверка recv ? recv(sock_client,(char*) &req,sizeof(req),0); do{recv(sock_client,&c,1,0);}while(c != 0);/* skip ident */ Вот тут вот в цикле имеет 100% шансы зависнуть при обрыве связи.
Бинарник качал, через него нет подключения аналогично(передавался hostort). В сорцах, в процедуре обработки данных различий принципиальных нет. Да на винде, уже который раз говорю, при чём тут этот кусок кода, вопрос у меня про socks5, а не socks4, код я не оптимизирую, зависнуть не боюсь. Вопрос конкретный, а не пространный. Данные от Миранды в сокс-сервер идут, из сокс-сервера на сервер icq идут, а дальше ни ответа ни привета. Вот копипаст из tcpview:
2 bad_boy принципиальные различия в проверке ответов сетевых функций и их корректная обработка. Сетевое программирование на самом деле не простая задача потому что нужно предусмотреть все возможные варианты сбоев и нагрузок на сеть и приложение. Сразу писать нужно с проверками, потому что "зависнуть" у тебя может в любом месте при приеме передаче подключении клиента и т.д. При одном тесте будет работать при другом нет, а ошибка в программе вообще не там
А вообще тут может быть что угодно, зависит еще от описания структуры или от таймаута который ставишь. и главное от той чёртовой либы которую ты используешь. Код который я вижу - это чисто linux кода и никогда в жизни он не скомпилится на Win с использованием WinSock. Потому что там нету функций таких как close и тому подобные. Если ты написал самописную обертку то тоже может быть глюк в ней. Возможно просто структурs для socks5 не правильно определены.