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

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

Вернуться   Форум программистов > Низкоуровневое программирование > Win Api
Регистрация

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

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

Ответ
 
Опции темы Поиск в этой теме
Старый 29.04.2014, 19:50   #1
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию WinSock, Не могу разорвать коннект!

Всем привет! Уже третьи сутки не могу разорвать все коннекты в приложении.

Есть серверное приложение, которое должно работать неделями без перезапуска.
Но из созданных 10к подключений, примерно 500-700 остаются висеть не закрытыми.

Я пытался и читать данные перед закрытием(думал вдруг нельзя закрыть пока не прочтёшь все данные с сокета, конечно идея бредовая, но проверяю всё, ибо реально задолбался)

Вот код, я сейчас так пытаюсь закрыть коннекты:

Код:
  r:integer;
  buff:array[0..10230] of char;
  TimeOutSSS:integer;
  l:linger;
  on_sock : LongInt;
begin
  on_sock:=1;
  TimeOutSSS:=2000;
  SetSockOpt(s,SOL_SOCKET, SO_RCVTIMEO, @TimeOutSSS, SizeOf(TimeOutSSS)); //ставлю таймаут, чтобы не долго ждать ecv сли нет данных
  ioctlsocket(s,FIONBIO,on_sock);//Пытался менять режим блокирующий/неблокирующий перед закрытием, все варианты лесом
  r:=winsock.shutdown(s,2); //Блокирую доступ к сокету(тут я и 0 и 1 и 2 пытался ставить во втором параметре)
  while (Recv(s,buff,sizeof(buff),0)>0) do sleep(50); //Забираю из него всю инфу
  l.l_linger:=0;
  l.l_onoff:=1;
  setsockopt(s,SOL_SOCKET,SO_LINGER,@l,sizeof(l)); //А об этом я на этом форуме где-то читал, мне не помогло
  closesocket(s);

Очень прошу подсказать как жестко, на 100% обрубить коннект.
Приветствуются любые ссылки на инфу(msdn читал про закрытие портов, чтото не видел нужной инфы)

p.s. код на делфи, но это не имеет значения, когда пишешь на винсок+винапи код делфи-си и наоборот переводится легко.

Всем заранее спасибо!
lollollollol вне форума Ответить с цитированием
Старый 29.04.2014, 21:23   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
из созданных 10к подключений, примерно 500-700 остаются висеть не закрытыми.
Глупый вопрос: А как определил что висят?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 29.04.2014, 21:37   #3
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Фаервол.
как набирает чуть больше 5к незакрытых, не может создать больше(сервак винда, такие ограничения)
lollollollol вне форума Ответить с цитированием
Старый 29.04.2014, 22:03   #4
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

А попробуй проверку поставить на closesocket
что она возвращает. Если не 0 то через WSAGetLastError() полуйчай код ошибки и пиши его в лог файл. Так хотя бы поймешь из-за чего может не закрываться.

P.S. А можешь выложить всю прогу?
А то я тут прослушки не вижу, и не могу понять как ты обустроил работу с несколькими сокетами...
I'm learning to live...

Последний раз редактировалось Stilet; 29.04.2014 в 22:06.
Stilet вне форума Ответить с цитированием
Старый 29.04.2014, 22:19   #5
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Забыл написать, делал, всегда ноль возвращает.

Выложить не могу,
Но работа с сокетами выполняется в потоке, 1 поток 1 сокет. Блокирующий режим.

Код:
var
  phe:PHostEnt;
  addr:sockaddr_in;
  sock:integer;
  error:integer;
  TimeOutSSS:integer;
begin
  phe := gethostbyname(PChar(domain));                                
  if (phe=nil) then begin
    result:=False;
    exit;
  end;
  addr.sin_family := AF_INET;
  addr.sin_port   := htons(port);
  addr.sin_addr   := PInAddr(phe.h_addr_list^)^;
  sock := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
  if (sock=INVALID_SOCKET) then begin
    result:=False;
    exit;
  end;
  TimeOutSSS:=2500;
  SetSockOpt(sock, SOL_SOCKET, SO_RCVTIMEO, @TimeOutSSS, SizeOf(TimeOutSSS));
  error := connect(sock, addr, sizeof(addr));
  if (error=SOCKET_ERROR) then begin
    result:=False;
  end else begin
    result:=True;
  end;
//Далее работа
//И тут попытка закрыть, как в первом посте

Последний раз редактировалось lollollollol; 29.04.2014 в 22:21.
lollollollol вне форума Ответить с цитированием
Старый 30.04.2014, 10:41   #6
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

10K потоков?!?
Прочитайте про SO_LINGER - может проблема в этом.

Так же вот еще материалы:
http://www.isi.edu/touch/pubs/infoco...nfocomm99-web/
http://stackoverflow.com/questions/7...e-wait-problem
http://msdn.microsoft.com/en-us/libr...v=bts.20).aspx
http://publib.boulder.ibm.com/infoce...ccllal0264.htm
waleri вне форума Ответить с цитированием
Старый 30.04.2014, 11:02   #7
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Цитата:
10K потоков?!?
Не может быть впринципе на винде столько потоков, максимум 2к на процесс

10к подключений в сумме набираются со временем. потоков 30.
Серверное ПО должно неделями не выключаться, и обрабатывать информацию/запросы

Цитата:
SO_LINGER
дак вот же, или не то?
Код:
l.l_linger:=0;
  l.l_onoff:=1;
  setsockopt(s,SOL_SOCKET,SO_LINGER,@l,sizeof(l));
сейчас почитаю.
lollollollol вне форума Ответить с цитированием
Старый 30.04.2014, 11:20   #8
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

Ссылки глянул, в реестре у меня вообще не было тех веток, создал, тоже самое
lollollollol вне форума Ответить с цитированием
Старый 30.04.2014, 12:12   #9
waleri
Старожил
 
Регистрация: 13.07.2012
Сообщений: 6,330
По умолчанию

Да, тот самый linger - я не заметил, что он есть...
Насчет отсуствия ключей в реестре - весьма странно. Может не туда смотрите? Не путаете LOCAL_MACHINE и CURRENT_USER?
waleri вне форума Ответить с цитированием
Старый 30.04.2014, 12:17   #10
lollollollol
Форумчанин
 
Регистрация: 23.03.2013
Сообщений: 218
По умолчанию

нет вроде,
HKEY_LOCAL_MACHINE\SYSTEM\CurrentCo ntrolSet\services\Tcpip\Parameters
(это с открытой ветки в regedit скопировал)

для теста быстро создаю 2к подключений, из них 80 остаются висеть.
Самое интересное что фаерволом их можно разорвать, а программой моей не могу.
Closesocket возвращает ноль.

Может быть существует какой-нибудь жесткий способ обрубить подключение? ну фаервол же как-то это делает(хотя он скорей всего это делает на уровне драйвера).


поигрался с лингером, такое впечатление что вообще никакой реакции. что с ним, что без него.
Может я неверно устанавливаю...
Долго гипнотизировал строку
setsockopt(s,SOL_SOCKET,SO_LINGER,@ l,sizeof(l));
но ничего не увидел...

Добавлю ещё что соединения отаются висеть, даже когда выхожу из потока
ExitThread(0), и закрываю хендл потока CloseHandle(ThID);
lollollollol вне форума Ответить с цитированием
Ответ


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



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Разорвать adsl соединение megostudent Работа с сетью в Delphi 5 28.03.2012 16:43
не могу сделать правильный пост запрос на winsock cable Работа с сетью в Delphi 0 10.07.2010 18:01
Разорвать Dial-Up соединение Михаил Юрьевич Работа с сетью в Delphi 0 19.12.2009 12:43
Как обработать не валидный коннект?(delphi,winsock) zotox Работа с сетью в Delphi 1 02.08.2009 19:46
Как разорвать связи? valerij Microsoft Office Excel 5 18.05.2009 23:36