![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
закрытие сокета другого потока [Win2k, WinXP]
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]Удалено модератором