Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Сети > Проблема с Winsock2 + TThread


Автор: Zib 13.12.2007, 07:58
Господа, доброго времени суток!
Пишу небольшой демо TCP сервер с использованием WinSock2. Сокет использую в блокирующем режиме. Для того, чтобы сокет не блокировал основной поток ф-я Accept вызывается в отдельном потоке TServerAcceptThread. Ф-я Recv также вызывается в отдельном потоке TServerRecvThread.
У принимающего коннекты потока есть событие - OnClientConnected, у читающего сокет - OnClientDisconnected и OnClientReceiveData. Для чего они полагаю понятно из названия.

Суть проблемы:
По непонятным причинам выкидывается AccessViolation в момент, когда клиент начинает слать данные. Думал, что проблема в том, что процедура события вызывается из потока несинхронизированно. Сихронизировал. Эффект = 0  smile 

Второй день бьюсь  smile немогу понять в чем дело. Поможите советом, плз.

Сырцы проекта прилагаю.

Автор: MetalFan 13.12.2007, 11:59
для передачи в кач.нетипизированного параметра дин.массивов и длинных строк надо использовать
их первый элемент.
не так:
Код

    FBuffer: array of byte;
...
    len := recv(Socket, FBuffer, FBufferSize, 0);

а так:
Код

    FBuffer: array of byte;
...
    len := recv(Socket, FBuffer[0], FBufferSize, 0);

пока это в глаза бросилось. посмотри подобные ошибки по коду

Добавлено через 10 минут и 21 секунду
так же идет асинхронное обращение к vcl в событиях HandleClientDisconnected, HandleClientReceiveData.
можно "обернуть" 
Код

procedure TncTcpServer.AddToLog(s: string);
begin
  //здесь добавить вход в крит.секцию
  frmServer.Memo.Lines.Add('[' + Self.ClassName + '] - ' + s);
  //здесь добавить выход из крит.секции
end;


также просто немного криво выглядит код:
Код

procedure TncTcpServer.HandleClientReceiveData(Socket: TSocket;
  buf: array of byte; len: integer);
var
  s: string;
  i: integer;
begin
  AddToLog('Handle client receive data');
  SetLength(s, len);
  for i := 0 to len - 1 do
    s[i+1] := chr(buf[i]);
  AddToLog(s);
end;

len вообще не нужен, ибо и так нам известна длина дин.массива
достаточно имхо такого кода:
Код

procedure TncTcpServer.HandleClientReceiveData(Socket: TSocket;
  buf: array of byte; len: integer);
var
  s: string;
begin
  AddToLog('Handle client receive data');
  SetString( s, PChar(buf[0]), Length(buf));
  AddToLog(s);
end;


Добавлено через 11 минут и 5 секунд
p.s. удачи

Автор: Zib 13.12.2007, 12:21
Цитата(MetalFan @  13.12.2007,  11:59 Найти цитируемый пост)
для передачи в кач.нетипизированного параметра дин.массивов и длинных строк надо использоватьих первый элемент.не так:код Pascal/Delphi1:2:3:    FBuffer: array of byte;...    len := recv(Socket, FBuffer, FBufferSize, 0);highlightSyntax('delphi_zZGM','delphi');highlightSyntax('delphi_zZGM','delphi');а так:код Pascal/Delphi1:2:3:    FBuffer: array of byte;...    len := recv(Socket, FBuffer[0], FBufferSize, 0);highlightSyntax('delphi_MmRhOD','delphi');highlightSyntax('delphi_MmRhOD','delphi');пока это в глаза бросилось. посмотри подобные ошибки по коду

Мммм.... Точно! Тупанул ащще  smile 
Собственно в этом и была проблема. Смутило именно то, что AccessViolation выскакивал не каждый раз, а както нерегулярно. Т.е. мог выскочить, а мог и нет.

В любом случае огромное спасибо, камрад! Буду внимательнее  smile 


Автор: Zib 13.12.2007, 12:42
Да, и совсем забыл еще спросить: как этот метод (на каждого клиента свой читающий поток) себя поведет в случае, если будет 100 клиентов, а 1000? Или тогда используются другие методы?

Автор: MetalFan 13.12.2007, 12:49
Zib, пулы потоков, порты завершения.
ищи по Thread Pool, http://www.gamedev.ru/community/mmorpg/articles/?id=6

Автор: Zib 14.12.2007, 14:09
Ща начну клянчить smile
Если кто располагает примером работы с IO Completion port на Дельфи поможите, буду весьма признателен!

Автор: MetalFan 14.12.2007, 14:18
есть же примеры несложные на C...

Автор: Zib 14.12.2007, 14:49
к сожалению сям необученыС...

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)