Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Сети";
Текущий архив: 2004.12.19;
Скачать: [xml.tar.bz2];

Вниз

Размер принимаемых данных   Найти похожие ветки 

 
QuestionX ©   (2004-10-08 22:58) [0]

Скажите, а если я отправляю по сети данных:
send(Socket, Buf, BufCount, 0);
то существует ли вероятность того, что данные на стороне сервера будут получены по частям, т.е. получится, что recv(Socket, Buf, BufCount, 0) < BufCount ?


 
VMcL ©   (2004-10-08 23:23) [1]

>>QuestionX ©  (08.10.04 22:58)

>существует ли вероятность того, что данные на стороне сервера будут получены по частям

Да, причем почти наверняка так и будет, особенно если BufCount больше аппаратного и/или программного буфера передающих систем.


 
Verg ©   (2004-10-08 23:24) [2]


> то существует ли вероятность того, что данные на стороне
> сервера будут получены по частям, т.е. получится, что recv(Socket,
> Buf, BufCount, 0) < BufCount ?


Для TCP (SOCK_STREAM) это вообще нормальная (штатная) ситуация. Мало того еще и send(Socket, Buf, BufCount, 0) < BufCount - тоже запросто.

Способ как дробить на части (или объединять) поток передаваемых (принимаемых) данных определяет транспортный протокол. Это его право в замен на гарантию доставки данных в неискаженном виде в пределах соединения.

Почти с точностью до наоборот дело обстоит с SOCK_DGRAM или SOCK_RAW...


 
QuestionX ©   (2004-10-09 00:34) [3]

А как обеспечить на стороне клиента прием заданного количества байт и чтобы поток при этом спал до момента полного приема ?


 
Verg ©   (2004-10-09 00:54) [4]

var
 Buf : array[0.. BUFSIZE - 1] of byte; // BUFSIZE - "заданное кол-во байтов"
 recvd : integer;
 DataSize : integer;

 DataSize := 0;
 while DataSize < BUFSIZE do
 begin
   recvd := recv(Socket, Buf[DataSize], BUFSIZE-DataSize, 0);
   if recvd <= 0 then
   begin
      if recvd = 0 then
      begin
        // Connection Closed Gracefully
        break;
      end else
        raise Exception.Create(SysErrorMessage(WSAGetLastError));
   end;
   inc(DataSize, recvd);
 end;
 if recvd > 0 then
   // Buf содержит ровно BUFSIZE байтов переданных "собеседником"


 
QuestionX ©   (2004-10-09 01:04) [5]


> Verg ©   (09.10.04 00:54) [4]

Спасибо !


 
QuestionX ©   (2004-10-09 01:11) [6]

А не подскажете еще, как можно сделать тоже самое, но еще и контролировать возможность тайм-аута операции ?


 
Rouse_ ©   (2004-10-09 01:37) [7]

> [6] QuestionX ©   (09.10.04 01:11)
функция select, последний параметр... (с учетом блокирующего состояния...)


 
QuestionX ©   (2004-10-09 02:17) [8]

Вот, написал:

procedure TClientThread.RequireBuffer(Buffer: Pointer; BufSize: Integer;
 TimeOut: Integer = -1);
var
 FDSet: TFDSet;
 TimeVal: TTimeVal;
 RecvBytes: Integer;
 ErrorCode: Integer;
begin
 repeat
   if TimeOut > 0 then
   begin
     FD_ZERO(FDSet);
     FD_SET(ClientSocket.SocketHandle, FDSet);
     TimeVal.tv_sec := 60;
     TimeVal.tv_usec := 0;
   end;
   if select(0, @FDSet, nil, @FDSet, @TimeVal) = SOCKET_ERROR then
   begin
     ErrorCode := WSAGetLastError;
     raise ESocketError.CreateResFmt(@sWindowsSocketError,
         [SysErrorMessage(ErrorCode), ErrorCode, "recv"]);
   end;
   if (ClientSocket.ReceiveLength = 0) or Terminated then
     raise ETerminated.Create("RequireBuffer");
   RecvBytes := ClientSocket.ReceiveBuf(PChar(Buffer)^, BufSize);
   if (RecvBytes = 0) or Terminated then
     raise ETerminated.Create("RequireBuffer");
   Dec(BufSize, RecvBytes);
   Inc(Cardinal(Buffer), RecvBytes);
 until BufSize <= 0;
end;


Есть замечания ?


 
Rouse_ ©   (2004-10-09 03:18) [9]

> [8] QuestionX ©   (09.10.04 02:17)
По ней ничего не видно, ибо:
if (ClientSocket.ReceiveLength = 0) - это непонятно откуда берется...
а также RecvBytes...

or Terminated - обычно в таких случаях лучше выставить в самом начале...


 
QuestionX ©   (2004-10-09 03:27) [10]


> if (ClientSocket.ReceiveLength = 0) - это непонятно откуда
> берется...

Это берется как проверка почему вышли из select - по таймауту или по пришествии данных

> а также RecvBytes...

А что RecvBytes ?

> or Terminated - обычно в таких случаях лучше выставить в
> самом начале...

select - операция продолжительная - могут в ее процессе и завершить.


 
Rouse_ ©   (2004-10-09 03:50) [11]

> [10] QuestionX ©   (09.10.04 03:27)
Не видно просто где у тебя инициализируются или обновляются эти переменные...

> select - операция продолжительная - могут в ее процессе
> и завершить.

Но перед ее вызовом ты должен проверить, а не хотят ли терминировать поток?


 
QuestionX ©   (2004-10-09 03:55) [12]


> Не видно просто где у тебя инициализируются или обновляются
> эти переменные...

ClientSocket - свойство объекта TClientThread, а RecvBytes как написано в процедуре так и работает...

> Но перед ее вызовом ты должен проверить, а не хотят ли терминировать
> поток?

Согласен.

А вот интересно, что будет если попытаютися закрыть приложение, пока поток ждет select ?


 
Rouse_ ©   (2004-10-09 04:07) [13]

> А вот интересно, что будет если попытаютися закрыть приложение,
> пока поток ждет select ?

В данном варинте (если использовать методы VCL) ничего не будет...
Выставится флаг Terminated и всего делов...


 
Rouse_ ©   (2004-10-09 04:12) [14]

Блин как всегда я не внимателен, прочитал "А вот интересно, что будет если попытаютися закрыть поток" ...
В данном случае другая сторона получит ошибку с кодом WSAECONNREFUSED


 
Rouse_ ©   (2004-10-09 04:16) [15]

точнее WSAEFAULT кажется :)
WSAECONNREFUSED для асинхронного сокета вывалится...

Эх блин, забыл матчасть.... :((


 
QuestionX ©   (2004-10-09 04:32) [16]


> В данном варинте (если использовать методы VCL) ничего не
> будет...
> Выставится флаг Terminated и всего делов...

Ничего не будет - это значит приложение не закроется или что ?


 
Rouse_ ©   (2004-10-09 04:59) [17]

> Ничего не будет - это значит приложение не закроется или
> что ?

Закроется конечно, главному потоку на второстепенный в принципе плевать при закрытии, хотя конечно лучше завершать потоки по честному  ;)


 
QuestionX ©   (2004-10-09 05:11) [18]


> Закроется конечно, главному потоку на второстепенный в принципе
> плевать при закрытии, хотя конечно лучше завершать потоки
> по честному  ;)

А разве главный поток не будет ждать завершения второстепенных ?


 
Verg ©   (2004-10-09 14:57) [19]

Я уже че-то не понимаю. То ли ты через WinsockAPI работал, то вдруг, откуда ни возьмись, появляется ClientSocket....
При том, на сколько можно только догадываться, в режиме ctBlocking...
Для работы в этом режиме, special for этот компонент есть специальный класс. Вполне приемлимая надстройка над блокирующим режимом.
TWinSocketStream - там есть и таймауты и проч...


 
QuestionX ©   (2004-10-09 15:09) [20]


> Я уже че-то не понимаю. То ли ты через WinsockAPI работал,
> то вдруг, откуда ни возьмись, появляется ClientSocket....

Имеется сервер - ThreadBlocking, так вот то, о чем я говорю - это один из потоков этого сервера. Ну а у них есть это свойство - ClientSocket. TWinSockStream - спасибо, посмотрел, но там read опять таки не ждет всего буфера, так что все равно переписывать...



Страницы: 1 вся ветка

Форум: "Сети";
Текущий архив: 2004.12.19;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.03 c
1-1102324352
Provodnick
2004-12-06 12:12
2004.12.19
В Image повторно загруженный рисунок не отображается!


1-1102149368
Gek1
2004-12-04 11:36
2004.12.19
Помогите разобраться. Глючит Format!


14-1101555931
X9
2004-11-27 14:45
2004.12.19
Софт для радиолюбителя...


8-1096206699
UserUserov
2004-09-26 17:51
2004.12.19
Media Player


14-1102017055
AYU
2004-12-02 22:50
2004.12.19
Дайте ссылки на что-нить интересное





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский