Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

закрытие сокета другого потока [Win2k, WinXP]


Страницы:   1 2

Ketmar ©   (2006-07-26 19:16:00) 

суть такая: есть n потоков, которые активно читают/пишут в совкеты. прокси-сервер, короче. %-) сокеты -- блокирующие.
в один печальный момент надо пришибить все эти потоки. как можно быстрее. сейчас я просто закрываю все сокеты, с которыми работают эти потоки (из отдельного потока-наблюдателя %-). вроде работает (за исключением сокета, который ожидает в connect() -- эти долго-долго думают %-(( ).
понимаю, что варварство, но ничего более умного сочинить не могу.
собственно, вопрос в том, наступал ли кто-то на грабли при таком жёстком изврате? или никто подобный невежливый код не пишет?

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

(не совсем уверен, что это не в WinAPI надо было...)


Медведъ   (2006-07-31 20:06:00) [1]

Удалено модератором


Ketmar   (2006-07-31 15:56:00) [2]

Удалено модератором


Медведъ   (2006-07-31 10:47:00) [3]

Удалено модератором


Ketmar   (2006-07-30 13:39:00) [4]

>Verg ©   (29.07.06 12:16) [25]
да. при медленной сети сокет в connect() уходит за пивом.

а делать лишний select() не хочу, потому что и так нечто подобное делает accept(). дублирование кода. %-)


Verg   (2006-07-29 12:16:00) [5]


> вроде работает (за исключением сокета, который ожидает в
> connect() -- эти долго-долго думают %-(( ).


И что? При connect-е "долго думают"?

Для блокирующего режима убийство сокета (из другого потока) - есть единственное универсальное средство прервать его думы по любому поводу.


> придётся делать select() и вызывать accept() только если
> кто-то пришёл. не хочется.


Эка невидаль или что, каприз?


Ketmar   (2006-07-28 18:08:00) [6]

Удалено модератором


Медведъ   (2006-07-28 17:24:00) [7]

Удалено модератором


Ketmar   (2006-07-28 16:52:00) [8]

Удалено модератором


Медведъ   (2006-07-28 16:43:00) [9]

Удалено модератором


Ketmar   (2006-07-28 16:16:00) [10]

Удалено модератором


Медведъ   (2006-07-28 14:41:00) [11]

Удалено модератором


Ketmar   (2006-07-28 14:36:00) [12]

>Медведъ   (28.07.06 14:17) [16]
цитирую себя же из [0]:
"я в курсе, что есть неблокирующие сокеты. огромная просьба меня не тыкать в них".
а про асинхронность вообще речи даже не начиналось.


Сергей М.   (2006-07-28 14:29:00) [13]


> Медведъ   (28.07.06 14:17) [16]


Асинхронность автора сего поста, заметь, интересует меньше всего.


Медведъ   (2006-07-28 14:17:00) [14]

Удалено модератором


Ketmar   (2006-07-28 10:44:00) [15]

Удалено модератором


Сергей М.   (2006-07-28 10:21:00) [16]

Удалено модератором


Медведъ   (2006-07-28 10:10:00) [17]

Удалено модератором


DiamondShark   (2006-07-28 00:45:00) [18]


> Ketmar ©   (26.07.06 19:20) [1]
> однако для сокета, который "слушает", вижу только одно решение
> -- прекратить "слушать" в блокирующем режиме. (то есть,
> не "слушать", конечно, а "принимать"). придётся делать select()
> и вызывать accept() только если кто-то пришёл. не хочется.
>  но, видимо, других вариантов нет -- кроме кривых хаков.
>  %-(

Зочем?
Вот примерчик накатал:

function AcceptThread(Param: Pointer): Integer;
const
 hello: PChar = 'Preved krosavcheg!';
var
 listenSocket: TSocket;
 client: TSocket;
 addr: TSockAddrIn;
 len: Integer;
 error: Integer;
 errorText: String;
begin
 Result := 0;
 listenSocket := TForm1(Param).FListenSocket;
 repeat
   len := sizeof(addr);
   client := accept(listenSocket, @addr, @len);
   if client = INVALID_SOCKET then break;
   send(client, hello^, StrLen(hello), 0);
   closesocket(client);
 until false;
 error := WSAGetLastError;
 errorText := SysErrorMessage(error);
end;

procedure TForm1.StartListen;
var
 Thread: THandle;
 ThreadId: DWORD;
 addr: TSockAddrIn;
begin
 FListenSocket := socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
 WinSockCheck(FListenSocket <> INVALID_SOCKET);

 addr.sin_family := AF_INET;
 addr.sin_port := htons(1024);
 addr.sin_addr.S_addr := htonl(INADDR_ANY);
 bind(FListenSocket, addr, sizeof(addr));
 listen(FListenSocket, SOMAXCONN);

 Thread := BeginThread(nil, 0, AcceptThread, self, 0, ThreadId);
 CloseHandle(Thread);
end;

procedure TForm1.StopListen;
begin
 if FListenSocket <> INVALID_SOCKET then
 begin
   closesocket(FListenSocket);
   FListenSocket := INVALID_SOCKET;
 end
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 StartListen;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 StopListen;
end;


При вызове closesocket(FListenSocket) accept возвращает WSAEINTR и замечательно завершается.


Сергей М.   (2006-07-27 16:13:00) [19]

Удалено модератором


Медведъ   (2006-07-27 16:08:00) [20]

Удалено модератором


Страницы:   1 2

Наверх

Титульная страница Поиск, карта сайта Написать письмо