Форум: "Сети";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];
Внизне доходит значение типа integer Найти похожие ветки
← →
Dmitry_177 (2007-04-28 22:14) [0]Использую WinSock, протокол TCP, может ли быть такое что не доходит значение типа integer? Просто так то у меня все работает, но иногда, очень редко бывает что недоходит значение типа integer, причем как-то странно то что именно в одном месте..
← →
Dmitrij_K (2007-04-29 11:45) [1]
> Использую WinSock, протокол TCP, может ли быть такое что
> не доходит значение типа integer?
нет
ошибка в 17-ой строке
← →
Belorus © (2007-04-29 14:37) [2]Согласен с Дмитрием.
← →
Dmitry_177 (2007-04-29 15:09) [3]просто у меня как-то странно то что в отладчике я вижу что отправляется, все как надо, а вот на принимающей стороне почему-то приходит число 0, хотя там не 0
← →
Dmitrij_K (2007-04-29 15:56) [4]Dmitry_177
ищи ошибку в коде
или отправляешь неправильно, или принимаешь или все вместе
← →
Dmitry_177 (2007-04-29 16:07) [5]на отправляющей стороне send(), на принимающей recv(), что здесь может быть неправильного? Я вот думаю то что потом странно как-то происходит, то что последующий вызов select и recv возвращают значение больше чем 0, а на самом деле ничего не отправлялось.. такое ощущение что при отправки этого числа, в буфере уже что-то есть и отправляется уже не число а ерунда.. только я посмотрел насчет этого, то вроде все нормально...((( как можно проверить есть ли данные буфере? или может очищать их как-то?
← →
Ketmar © (2007-04-29 17:03) [6]а может вам, барин, сначала почитать умные книги по WinSock и TCP? тогда не будет феерических вопросов типа "может, буфер как-то очистить?"
и настоятельно советую проверить 17-ю строку. она, зараза, часто шибко кривая.
← →
DVM © (2007-04-30 16:58) [7]Пиши как отправлял, как принимал - тогда будет видно. Так со слов понять в чем проблема сложно.
← →
Сергей М. © (2007-05-02 08:34) [8]
> что здесь может быть неправильного?
Неправильным может быть отсутствие в твоем алгоритме анализа результатов, которые эти функции возвращают.
← →
Dmitry_177 (2007-05-02 11:26) [9]Вот сильно упрощенный вариант..
http://slil.ru/24318084
Нужно запустить KLServer.exe, потом KLClient.exe, там прописать свой же IP если сервер запущен на этом же компьютере и нажать "Connect", потом если нажимать много раз "Find"(бывает с и с первого раза, бывает на 20й), бывает выскакивает "1 Ошибка", вот с чем это связано никак не пойму... Подскажите пожалуйста..
← →
Сергей М. © (2007-05-02 11:40) [10]
> выскакивает "1 Ошибка", вот с чем это связано никак не пойму
С тем что SelectDataPacket.Code = 0
А вообще код в TForm1.Button2Click просто жуткий, разбираться в этой "лестнице" нет никакого желания.
← →
clickmaker © (2007-05-02 11:41) [11]
> [9] Dmitry_177 (02.05.07 11:26)
архив поврежден
Ты бы лучше код показал
← →
Dmitry_177 (2007-05-02 11:54) [12]Выкладываю:
Exchange.pas
unit Exchange;
interface
uses
Windows;
const
KL_HELLO = 111;
KL_HELLO_OK = 222;
KL_FIND = 001;
KL_FIND_OK = 002;
KL_FIND_NEXT = 003;
KL_CHECK = 100;
KL_CHECK_OK = 200;
KL_EXIT = 999;
type
TDataPacket = packed record
Name: array [0 .. 254] of Char;
UrAddress: array [0 .. 254] of Char;
FkAddress: array [0 .. 254] of Char;
Telephone: array [0 .. 54] of Char;
Fax: array [0 .. 54] of Char;
Email: array [0 .. 54] of Char;
WWWPage: array [0 .. 254] of Char;
Activity: array [0 .. 254] of Char;
Director: array [0 .. 254] of Char;
ContPerson: array [0 .. 254] of Char;
Bank: array [0 .. 254] of Char;
INN: array [0 .. 254] of Char;
SetAccount: array [0 .. 254] of Char;
CorAccount: array [0 .. 254] of Char;
BIK: array [0 .. 254] of Char;
OKPO: array [0 .. 254] of Char;
Okato: array [0 .. 254] of Char;
KPP: array [0 .. 254] of Char;
NContract: array [0 .. 254] of Char;
LowDate: SYSTEMTIME;
HightDate: SYSTEMTIME;
Note: array [0 .. 254] of Char;
end;
TSelectDataPacket = packed record
Name: array [0 .. 254] of Char;
Code: Longint;
end;
TFindDataPacket = packed record
DataPacket: TDataPacket;
ContractType: (ctNContract, ctLowDate, ctHightDate, ctNone);
end;
implementation
end.
← →
Dmitry_177 (2007-05-02 11:57) [13]Блин, слишком длинный код, по частям долго добавлять.. Еще раз залил архив:
http://slil.ru/24318225
← →
Сергей М. © (2007-05-02 12:37) [14]
> Dmitry_177 (02.05.07 11:26) [9]
Если ты вызовом recv() запросил к чтению N байт и ф-ция возвратила рез-т >= 0, то это вовсе не означает , что приняты запрошенные N байт !!!!
← →
Dmitry_177 (2007-05-02 15:02) [15]а что тогда делать? вызывать заново recv? как тогда мне получить значение типа integer и структуру TSelectDatapacket из этих двух recv-ов?
← →
DVM © (2007-05-02 15:35) [16]
> а что тогда делать? вызывать заново recv?
во первых она говорит сколько байт реально прочитано, а во вторых в цикле вызывай пока не получишь все.
← →
DVM © (2007-05-02 15:36) [17]recv не знает ничего о TSelectDatapacket - она байты принимает
← →
Сергей М. © (2007-05-02 15:42) [18]
> вызывать заново recv?
Да.
> как тогда мне получить значение типа
Вызывать recv до тех пор, пока не будут получены все данные требуемого размера.
> из этих двух recv-ов
Почему двух ?
Если ты ожидаешь, скажем , SizeOf(Integer)=4 байта, то теоретически может потребоваться от одного до четырех вызовов recv.
← →
Dmitry_177 (2007-05-02 15:53) [19]а как тогда все это склеить? к примеру integer был принят двумя recv-ами, как его склеить в одно?
← →
Dmitry_177 (2007-05-02 16:03) [20]на сколько я понимаю, нужно считывать в какой-то буфер, а как его объявлять? и как потом из него считать тот же integer?
← →
Сергей М. © (2007-05-02 16:04) [21]
> Dmitry_177 (02.05.07 15:53) [19]
Забудь на время про recv.
Простейший тест на знания Паскаля:
Если у тебя есть, к примеру, есть 4 байта, то как получить из них Integer, если имеющиеся байты следуют в Intel-порядке - от младшего к старшему ?
← →
Dmitry_177 (2007-05-02 16:16) [22]Так?
var
i: integer
Buffer: array of Byte;
SetLength(Buffer, SizeOf(i));
Move(Buffer, i, SizeOf(i));
← →
SpellCaster (2007-05-02 16:30) [23]Можно и так
var
i: integer
Buffer: array [1..sizeof(integer)] of Byte absolute i;
← →
Сергей М. © (2007-05-02 16:33) [24]
> Dmitry_177 (02.05.07 16:16) [22]
Ну пусть даже так.
А теперь представь, что буфер Buffer заполняется полученными в рез-те вызовов ф-ции recv данными - первый полученный байт помещается в Buffer[0], второй - в Buffer[1], третий - в Buffer[2], N-ный - в Buffer[N-1] ..
← →
Dmitry_177 (2007-05-02 16:37) [25]мне не очень понятно вот что: вот был вызван recv(KLSock, Buffer, SizeOf(Buffer), 0), вернул он например 2, т.е. было получено 2 байта, как мне потом при вызове следующего recv записать в конец данных в буфере а не в начало, т.е. не на те которые уже были приняты? Вот так: recv(KLSock, Buffer[3], SizeOf(Buffer)-2, 0)? и как мне реализовать лучше этот цикл? и еще при следующих вызовах recv сколько задавать на получение байт(3 параметр)? так как я уже привел: SizeOf(Buffer)-2?
← →
Dmitry_177 (2007-05-02 16:53) [26]я вот так придумал:
var
b: bool;
i: integer;
iRecv: integer;
RecvSize: integer;
Buffer: array of Byte;
begin
b := false;
i := 0;
SetLength(Buffer, SizeOf(iRecv));
while not b do
begin
RecvSize := recv(KLSock, Buffer[i], SizeOf(Buffer), 0);
if RecvSize = Socket_Error then
begin
Break;
Exit;
end;
if RecvSize <> SizeOf(Buffer) then
begin
Move(Buffer[i], iRecv, RecvSize);
i := i + RecvSize;
end
else
b := true;
end;
end;
Правильно ли так будет или можно как-то проще и лучше?
← →
Сергей М. © (2007-05-02 16:56) [27]var
buf: Pointer;
BytesNeed: Integer;
BytresRead: Integer;
MyData: TMyType; //TMyType м.б. и Integer, и TSelectDataPacket, и что угодно
..
buf := @MyData;
BytesNeed := SizeOf(MyData);
while BytesNeed > 0 do begin
BytesRead := recv(KLSock, buf^, Min(BytesNeed, SizeOf(buf));
if BytesRead >= 0 then begin
Dec(BytesNeed, BytesRead);
Inc(DWord(buf), BytesRead);
end else
..
end;
← →
Dmitry_177 (2007-05-02 17:21) [28]а как посылать лучше структуру TSelectDataPacket?
send(KLSock, SelectDataPacket, SizeOf(SelectDataPacket), 0) или надо по кускам?
← →
Сергей М. © (2007-05-02 17:25) [29]
> или надо по кускам?
Об этом тебе скажет результат вызова send(), точно так же как результат вызова recv() говорит тебе о том, все ли из запрошенного тобой к чтению фактически прочитано.
← →
Dmitry_177 (2007-05-02 17:49) [30]Чтобы каждый раз не мучаться при каждой посылке или приеме информации, я думаю лучше написать функции с этим циклом и уже их использовать.. Вот например с recv:
function NewRecv(s: TSocket; var Buf; len, flags: Integer): Integer;
var
BytesNeed: Integer;
BytresWrite: Integer;
begin
BytesNeed := len;
while BytesNeed > 0 do
begin
BytesRead := recv(s, Buf, BytesNeed, flags);
if BytesRead = SOCKET_ERROR then
begin
Result := SOCKET_ERROR;
Break;
Exit;
end;
if BytesRead = 0 then
begin
Result := len - BytesNeed;
Break;
Exit;
end;
if BytesRead > 0 then
begin
Dec(BytesNeed, BytesRead);
Inc(DWORD(Buf), BytesRead);
end;
end;
Result := len;
end;
Правильно ли так будет?
← →
DVM © (2007-05-02 18:07) [31]
> Dmitry_177 (02.05.07 17:49) [30]
я вот так делаю:
function THTTPInputThread.ReadData(ABuffer: TBuffer; BytesExpected: integer): integer;
const
MaxLen = 262144;
var
TotalBytesToRead, Found, TotalBytesRead, BytesToRead, BytesRead: integer;
Rfds: TFDSet;
TempBuff: array [0..Pred(MaxLen)] of Char;
begin
FD_ZERO(Rfds);
FD_SET(Sock, Rfds);
Found := select(Sock, @Rfds, nil, nil, @FTimeout);
if Found = 0 then
begin
// Select timed out
Result := -1;
exit;
end
else
if Found = SOCKET_ERROR then
begin
// Select error
Result := -1;
exit;
end;
TotalBytesToRead := 0;
if BytesExpected <> 0 then
begin
TotalBytesToRead := BytesExpected;
end
else
begin
if ioctlsocket(Sock, FIONREAD, TotalBytesToRead) = SOCKET_ERROR then
begin
// Cannot ioctl()
Result := -1;
exit;
end;
if TotalBytesToRead = 0 then
begin
SocketDisconnect();
Result := 0;
exit;
end;
end;
TotalBytesRead := 0;
repeat
if TotalBytesToRead > MaxLen then
BytesToRead := MaxLen
else
BytesToRead := TotalBytesToRead;
ZeroMemory(@TempBuff[0], MaxLen);
BytesRead := recv(Sock, TempBuff, BytesToRead, 0);
if BytesRead = SOCKET_ERROR then
begin
// Read error
SocketDisconnect();
Result := -1;
exit;
end
else
if BytesRead = 0 then
begin
SocketDisconnect();
Result := 0;
exit;
end
else
begin
if ABuffer.Size >= 2097152 then
begin
SocketDisconnect();
Result := -1;
exit;
end;
ABuffer.Append(@TempBuff[0], BytesRead);
TotalBytesRead := TotalBytesRead + BytesRead;
TotalBytesToRead := TotalBytesToRead - BytesRead;
end;
until TotalBytesToRead <= 0;
Result := TotalBytesRead;
end;
← →
Dmitry_177 (2007-05-03 00:02) [32]Странно как-то.. Используя тот код который я привел выше, посылаю значение типа integer равное "1", получаю "5"
← →
Dmitry_177 (2007-05-03 00:06) [33]Потом чисто ради эксперимента послал "111", получил "115"
← →
Dmitry_177 (2007-05-03 00:20) [34]как я понял всегда прибавляется на 4.. Наверно это из-за этого: Inc(DWORD(Buf), BytesRead); но эта же строка тоже нужна для того чтобы не в начало буфера записывались последующие вызовы recv.. Что можно с этим сделать?
← →
Dmitry_177 (2007-05-03 10:05) [35]Попробовал вот так:
function KLRecv(s: TSocket; var Buf; len, flags: Integer): Integer;
var
PBuf: Pointer; // чтобы двигать ЭТОТ указатель
BytesNeed: Integer;
BytesRecv: Integer;
FDSet: TFDSet;
TimeOut: TimeVal;
begin
FD_ZERO(FDSet);
FD_SET(s, FDSet);
TimeOut.tv_sec := 60;
TimeOut.tv_usec := 0;
PBuf := @Buf;
BytesNeed := len;
while BytesNeed > 0 do
begin
if select(0, @FDSet, nil, nil, @TimeOut) > 0 then // чтобы не застопорился на recv
begin
BytesRecv := recv(s, PBuf^, BytesNeed, flags);
if BytesRecv > 0 then
begin
Dec(BytesNeed, BytesRecv);
Inc(DWORD(PBuf), BytesRecv);
end
else
begin
Result := SOCKET_ERROR; // это чтобы в самой программе не сверять размер полученных байтов, т.к. всеравно они не все пришли, мне проще сделать это как ошибка SOCKET_ERROR, хоть даже сколько то и было полученно байт..
Break;
Exit;
end;
end
else
begin
Result := SOCKET_ERROR; // тоже самое
Break;
Exit;
end;
end;
Result := len;
end;
и в самой программе:
if KLRecv(KLSock, iRecv, SizeOf(iRecv), 0) <> SOCKET_ERROR then
...
всеравно если посылаю 1 приходит 5, как я понимаю к значению прибавляется размер получаемых данных, т.к. integer 4 байта занимает вот они и прибавляются.. подскажите пожалуйста..
Страницы: 1 вся ветка
Форум: "Сети";
Текущий архив: 2008.01.13;
Скачать: [xml.tar.bz2];
Память: 0.55 MB
Время: 0.007 c