-
Приветствую! Проблема в следующем. При оправке пакета с одного ПК на удаленный ПК, через интернет, пакет обрезается примерно на 1415 байтах. Однако по локальной сети - все работает. Для передачи данных использую библиотеки от Overbyte. А вот и сама передающая процедура:
procedure TThrdSrvForm.SendTCPToClient(Client : TMyClient; sMs:AnsiString);
var
SendRes:integer;
Ms1, Ms2 :TMemoryStream32;
i:integer;
begin
try
Ms1:= TMemoryStream32.Create;
Ms2:= TMemoryStream32.Create;
Ms1.Size:= Length(sMs);
move(pointer(sMs)^, Ms1.Memory^, Length(sMs));
Ms1.Position:=0;
ztvCompress_StreamToStream(Ms1, Ms2, Ms1.Size, ztvCompressLevel); Ms2.Position:=0;
SendRes:=Client.Send(Ms2.memory, Ms2.Size);
SizeOut(SendRes); finally
Ms1.Free;
Ms2.Free;
end;
end; В интернете прочитал: Длина дейтаграммы. Это полная длина IP-дейтаграммы (заголовок плюс данные) в байтах. Поскольку размер этого поля равен 16 бит, теоретически максимальный размер IP-дейтаграммы может составлять 65 535 байт. Однако размер дейтаграмм редко превосходит 1500 байт и обычно ограничивается значением 576 байт.Неужели в этом кроется проблема?? Какие решения можете предложить по улучшению кода?
-
а прием пакетов происходит вот так: procedure TDataTCP.WSocketDataAvailable(Sender: TObject; ErrCode: Word);
var
RecvRes: Integer;
buffer: array [0..65506] of Byte;
j,i,k : LongInt;
ss:string;
Ms1:TMemoryStream32;
Ms2:TMemoryStream32;
sMs:AnsiString;
begin
RecvRes := WSocket.Receive(@buffer, SizeOf(buffer));
if RecvRes <= 0 then Exit;
try
try
Ms1:= TMemoryStream32.Create;
Ms2:= TMemoryStream32.Create;
Ms1.WriteBuffer(buffer, RecvRes); Ms1.Position := 0;
ztvInflate.ztvDecompress_StreamToStream(Ms1, Ms2, Ms1.Size); Ms2.Position := 0;
SetLength (sMs,Ms2.Size);
Ms2.Read(sMs[1],Length(sMs));
except
log('Ошибка распаковки данных');
end;
finally
Ms1.Free;
Ms2.Free;
end;
end;
-
Помогите! Где ошибки в коде?
-
> При оправке ..пакет обрезается
На оновании чего ты утверждаешь это ?
-
> При оправке пакета с одного ПК на удаленный ПК, через интернет, > пакет обрезается примерно на 1415 байтах. >
Ну логично, что данные помещаются в пакеты, меньшие по размеру чем стандартный максимальный размер Ethernet фрейма, но откуда ты узнал размер пакета? Это можно узнать только с помощью снифера.
-
> DVM © (15.11.12 22:49) [4]
"Пакетом" он видимо окрестил содержимое отправляемого стрима.
Если воспринимать его заяву дословно, то "1415" он узрел на главной форме в результате выполнения строчки
> SizeOut(SendRes)
что если и вероятно, то для UDP-транспорта, но не для TCP.
-
Мама мыла раму. Папа пил пиво. Это 2 сообщения. как Ты определил что их тут два? Две точки! (Знак препинания) Казнить нельзя помиловать Чего не хватает? Запятой! (Знак препинания) теперь про твоих баранов
<------Размер пакета-------> 1различная строковая информа ция2различная строковая инфо рмация3различная строковая и нформация как компьютер определит что тут 3 сообщения?
-
> > > При оправке ..пакет обрезается > > > На оновании чего ты утверждаешь это ?
Сервер клиенту отправляет пакет размером 2400 байт. Но клиент принимает 1490 байт. Размер узнал строчкой RecvRes := WSocket.Receive(@buffer, SizeOf(buffer));
-
> Мама мыла раму. Папа пил пиво. > Это 2 сообщения. как Ты определил что их тут два? Две точки! > (Знак препинания) > Казнить нельзя помиловать > Чего не хватает? Запятой! (Знак препинания) > теперь про твоих баранов > > <------Размер пакета-------> > 1различная строковая информа > ция2различная строковая инфо > рмация3различная строковая и > нформация > как компьютер определит что тут 3 сообщения?
Ребята, давайте без сарказма. Просто помогите пожалуйста исправить вышеуказанный код. Согласен, что я делаю не правильно. Но я создал эту тему с просьбой о помощи по конкретному моему случаю. Надеюсь найдутся добрые люди и помогут исправленным кодом. Заранее спасибо!
-
никаких «пакетов» на уровне TCP нет. есть соединение, по которому передаётся поток байт до тех пор, пока оно не разорвано.
-
> никаких «пакетов» на уровне TCP нет. > есть соединение, по которому передаётся поток байт до тех > пор, пока оно не разорвано.
Да понял что пакеты только у UDP. Но в моем случае что не так? Почему обрывается?? И что в коде не так?
-
Помогите исправленным кодом
-
> чы (16.11.12 09:35) [10]
почему вы считаете, что оно обрывается? в хелпе на WSocket.Receive сказано, что она дожидается разрыва соединения? подозреваю, что нет (сам библиотекой от Overbyte не пользуюсь).
-
> почему вы считаете, что оно обрывается? > в хелпе на WSocket.Receive сказано, что она дожидается разрыва > соединения? > подозреваю, что нет (сам библиотекой от Overbyte не пользуюсь). >
Ну потому что я отправляю данные. А приходит только кусок.
-
в общем случае, их и нельзя принять целиком (представьте, что поток данных идёт с веб-камеры). к обрыву это не имеет отношения.
-
> А приходит только кусок
Куда приходит-то ? Изначально ты заявил что "при отправке", теперь ты заявляешь что "при приеме"..
-
И снова возвращаемся к нашим баранам. Проблема в том, что принимающая сторона не приняла весь зашифрованный пакет. Для этого нужно при отправке в заголовке указывать 4 байта с размером передаваемого пакета, затем передавать сам пакет. Я сделал подобное. Но тут проблема в том, что код не работает. И где ж опять ошибка???? А вот отправляющая: procedure TThrdSrvForm.SendTCPToClient(Client : TMyClient; sMs:AnsiString);
var
size:integer;
Ms1, Ms2 :TMemoryStream32;
i:integer;
begin
try
Ms1:= TMemoryStream32.Create;
Ms2:= TMemoryStream32.Create;
DisplayOutTcp('===='+Client.Nick+'===='+FormatDateTime('dd/mm/yyyy(hh:nn:ss)', Now)+'====');
DisplayOutTcp(sMs); Ms1.Size:= Length(sMs);
move(pointer(sMs)^, Ms1.Memory^, Length(sMs));
Ms1.Position:=0;
ztvCompress_StreamToStream(Ms1, Ms2, Ms1.Size, ztvCompressLevel); Ms2.Position:=0;
size := Ms2.Size;
Client.Send(@size, SizeOf(size));
Client.Send(Ms2.memory, Ms2.Size);
SizeOut(size); finally
Ms1.Free;
Ms2.Free;
end;
end; вот у меня принимающая процедура: procedure TDataTCP.WSocketDataAvailable(Sender: TObject; ErrCode: Word);
var
RecvRes: Integer;
j,i,k : LongInt;
ss:string; Ms1:TMemoryStream32;
Ms2:TMemoryStream32;
sMs:AnsiString;
begin
RecvRes := WSocket.Receive(@buffer[BufSize], SizeOf(buffer) - BufSize);
Writeln('recv buf: ', RecvRes);
if not (RecvRes = INVALID_SOCKET) then BufSize := BufSize + RecvRes;
if (BufSize >= 4) then Writeln('packet size: ', PInteger(@buffer)^, ' buf size: ', BufSize - 4);
if ((BufSize >= 4) and (PInteger(@buffer)^ = BufSize - 4)) then
begin
Writeln('ok ');
try
try
Ms1:= TMemoryStream32.Create;
Ms2:= TMemoryStream32.Create;
Ms1.WriteBuffer(buffer[4], BufSize - 4); Ms1.Position := 0;
ztvInflate.ztvDecompress_StreamToStream(Ms1, Ms2, Ms1.Size); Ms2.Position := 0;
SetLength (sMs,Ms2.Size);
Ms2.Read(sMs[1],Length(sMs));
except
log('Ошибка распаковки данных или записи их в tstrings');
end;
finally
Ms1.Free;
Ms2.Free;
end;
FormMain.fGameEng.vvv(sMs);
Writeln('ok ');
BufSize := 0;
end;
end;
-
> код не работает
И не будет пока не воспользуешься отладчиком.
-
> > > код не работает > > > И не будет пока не воспользуешься отладчиком.
все понятно. один сарказм, а помощи никакой. Если не можете или не хотите помочь - тогда просто промолчите
-
Да какой сарказм ? Суровая правда жизни.
-
Сергей М. © Вы никогда не можете дать дельного совета. Вы как троль. Только тролите, а помоч никому не хотите и по всей видимости не можете
-
> не хотите и по всей видимости не можете
на боевй патриотизм берешь?
-
> боевй
*боевой
-
> xss22 © (19.11.12 18:55) [20]
Я тебе еще в [3] задал вполне ясный и конкретный вопрос. И до сего момента ты НЕ удосужился на него ответить. Тебе чего надо-то, обиженный ? Чтобы я все бросил и изучил-оттрассировал твой код, в то время как ты даже не удосужился вменяемо описать что у тебя там конкретно не работает ?
-
xss22 ©Вот ты отправляешь данные: Client.Send(@size, SizeOf(size));
Client.Send(Ms2.memory, Ms2.Size); Скажи, где ты прочитал, что в ответ на это, два ( 2) раза будет вызван твой procedure TDataTCP.WSocketDataAvailable(Sender: TObject; ErrCode: Word); ?!
-
cobalt © (20.11.12 10:01) [24] Скажи, где ты прочитал, что в ответ на это, два (2) раза будет вызван твой Это все происки злобных неблокирующих сокетов :) Гораздо все проще в блокирующем режиме TClientSocket\TServerSocket... если Автару все еще интересно, пеши сюды или мыли проект в меня
|