От година и кусур пиша програми работещи с интернет протоколи на Delphi. Ползвам Ararat Synapse, който си е на основа WinSock. Компонента е лек, горе долу добре написан и върши работа за многонишкови приложения. Последно време обаче започвам да му забелязвам някой проблеми, които хич не ми харесват.
Реших да си напиша нещо мое пак с WinSock. Synapse е със синхронни сокети, решавам мойто да е със асинхронни уж за по-бързо и по-добре. Отначало имах малко проблеми докато разбера коя функция за какво е, как да използвам WinSock events и така нататък. И така почти съм готов и решавам да тествам. Директни заявки с http минават без проблем.
Реших да сложа и възможност за SOCKS4 проксита. Добавих го лесно. При теста обаче се натъкнах на гаден проблем. Ако проксито е в ред пускам connect и чакам на FD_CONNECT event за да съм сигурен че съм се закачил. Събитието си идва и аз си продължавам нататък. Ако обаче проксито е мъртво и пробвам да се закача за затворен порт например се получава следното:
- connect минава.
- WaitForSingleObject на event FD_CONNECT се сигналва.
- WSAGetLastError връща WSAEWOULDBLOCK.
Всичко това ме завърта в безкраен цикъл и единственото, което ме спира е таймаут. Въпреки че конекцията отдавна е затворена аз вися като прани гащи до таймаут. Накрая стигнах до решението да гледам връзката с WireShark. Правя заявката пуска се пакет SYN, машината със затворения порт ми връща RST, ACK. Така три пъти и дотам.
Започнах да се питам защо WSAGetLastError не ми връща грешка че връзката е вече затворена? След малко повече ровене по MSDN и Google се оказа, че WSAGetLastError връща само грешки за WinSock, и ако искам да видя какво става с връзката трябва да викам getsockopt с опция SO_ERROR. Това последното наистина ми върна вярната грешка. Проблема в крайна сметка реших като викнах и двете функции. Ако getsockopt върне грешка взимам нея, инъче карам със WSAGetLastError.
/me доволен :D
Реших да си напиша нещо мое пак с WinSock. Synapse е със синхронни сокети, решавам мойто да е със асинхронни уж за по-бързо и по-добре. Отначало имах малко проблеми докато разбера коя функция за какво е, как да използвам WinSock events и така нататък. И така почти съм готов и решавам да тествам. Директни заявки с http минават без проблем.
Реших да сложа и възможност за SOCKS4 проксита. Добавих го лесно. При теста обаче се натъкнах на гаден проблем. Ако проксито е в ред пускам connect и чакам на FD_CONNECT event за да съм сигурен че съм се закачил. Събитието си идва и аз си продължавам нататък. Ако обаче проксито е мъртво и пробвам да се закача за затворен порт например се получава следното:
- connect минава.
- WaitForSingleObject на event FD_CONNECT се сигналва.
- WSAGetLastError връща WSAEWOULDBLOCK.
Всичко това ме завърта в безкраен цикъл и единственото, което ме спира е таймаут. Въпреки че конекцията отдавна е затворена аз вися като прани гащи до таймаут. Накрая стигнах до решението да гледам връзката с WireShark. Правя заявката пуска се пакет SYN, машината със затворения порт ми връща RST, ACK. Така три пъти и дотам.
Започнах да се питам защо WSAGetLastError не ми връща грешка че връзката е вече затворена? След малко повече ровене по MSDN и Google се оказа, че WSAGetLastError връща само грешки за WinSock, и ако искам да видя какво става с връзката трябва да викам getsockopt с опция SO_ERROR. Това последното наистина ми върна вярната грешка. Проблема в крайна сметка реших като викнах и двете функции. Ако getsockopt върне грешка взимам нея, инъче карам със WSAGetLastError.
/me доволен :D



