Форум: "Сети";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
ВнизКак правильно послать файл через TcpServer & TcpClient ? Найти похожие ветки
← →
Andrewtitoff © (2008-01-18 10:57) [0]Пытаюсь послать файл, файл посылается, но прога все время вываливается с ошибками:
Access violation, Canvas does not allow drawing... =(((
И как при приеме узнать размер пересылаемого файла что бы засунуть его в ReceiveBuf.., SizeOf(Buf) возвращает все время 4 ... =(((
Вот текст моей программы:
================================================
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms, Dialogs, Sockets, StdCtrls;
type
TMyChat = class(TForm)
Label1: TLabel;
Label2: TLabel;
Label3: TLabel;
RemoteHost: TEdit;
RemotePort: TEdit;
LocalPort: TEdit;
Display: TMemo;
Edit: TEdit;
Connect: TButton;
TcpServer1: TTcpServer;
TcpClient1: TTcpClient;
SendFile: TButton;
procedure TcpServer1Accept(Sender: TObject; ClientSocket: TCustomIpClient);
procedure SendClick(Sender: TObject);
procedure ConnectClick(Sender: TObject);
procedure SendFileClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
end;
var
MyChat: TMyChat;
implementation
{$R *.dfm}
procedure TMyChat.ConnectClick(Sender: TObject);
begin
TcpServer1.LocalPort := LocalPort.Text;
TcpServer1.Active := True;
TcpClient1.RemotePort := RemotePort.Text;;
TcpClient1.RemoteHost := RemoteHost.Text;;
TcpClient1.Active := True;
end;
procedure TMyChat.FormClose(Sender: TObject; var Action: TCloseAction);
begin
TcpServer1.Active := False;
TcpClient1.Active:= False;
TcpClient1.Disconnect;
end;
procedure TMyChat.SendFileClick(Sender: TObject);
var
asd:Tmemorystream;
begin
asd := TMemoryStream.Create;
asd.Position:=0;
asd.LoadFromFile("c:\1.txt");
asd.Position:=0;
TcpClient1.Active := True;
try
if TcpClient1.Connect then
begin
TcpClient1.SendStream(asd);
end;
finally
TcpClient1.Disconnect;
end;
asd.free;
end;
procedure TMyChat.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
s:string;
asd:tmemorystream;
len:integer;
buf:pointer;
begin
asd:=TMemoryStream.Create;
asd.Position:=0;
len:= ClientSocket.ReceiveBuf(buf,192,0);
asd.WriteBuffer(buf,len);
asd.SaveToFile("c:\000.txt");
asd.Free;
FreeMem(Buf);
clientsocket.Close;
ShowMessage("clientsocket.Close");
end;
end.
================================================
← →
Сергей М. © (2008-01-18 12:53) [1]
> SizeOf(Buf) возвращает все время 4
А сколько он, по твоему, должен возвратить, если переменная buf имеет указательный тип ?
← →
Slym © (2008-01-18 13:20) [2]Andrewtitoff © (18.01.08 10:57)
ClientSocket.ReceiveBuf(buf,192,0);
а память выделит папа Карло?GetMem(buf,1024);
len:= ClientSocket.ReceiveBuf(buf,1024,0);
asd.WriteBuffer(buf,len);
FreeMem(buf)
илиvar buf:array[0..1023] of byte;
← →
Andrewtitoff © (2008-01-18 13:55) [3]2 Slym
Спасибо, тока ничего не изменилось.. =((( тока если в ClientSocket.ReceiveBuf размер пишу 1024 как у тебя то почему то Len = -1, а если 192 как раньше(192 - это размер пересылаемого мною при тестировании файла) то все та же ошибка "Canvas does not allow drowing"... =(((
2 Сергей М.
Так а как мне узнать размер пересылаемого файла?, раньше в TClientSocket
писалось Len:=Socket.ReceiveLength;, а теперь как?... =((((
← →
Сергей М. © (2008-01-18 15:02) [4]
> как мне узнать размер пересылаемого файла?
А ты его отправлял, этот размер, прежде чем его принимать ?
> раньше в TClientSocket
> писалось Len:=Socket.ReceiveLength
Раньше у власти были коммуняки, мало ли какая фигня при них "писалась")
> а теперь как?
А теперь следует думать головой - если размер ты не отправил, то и принять его не сможешь.
← →
Andrewtitoff © (2008-01-18 15:16) [5]2 Сергей М
Ясно, ну с размером конечно это не очень хороше, но в общем то мне все понятно, отправлю - не вопрос...
Так а в чем у меня еще ошибка то, я когда тестиркю размер файла то знаю, и его вписываю, тока пересылать то он пересылается, тока после этого программа с треском вываливается или всю систему вешает... =(((
← →
Сергей М. © (2008-01-18 15:18) [6]
> пересылать то он пересылается
Где ?!!
Покажи хоть малейший намек на это в приведенном тобой коде ..
← →
Palladin © (2008-01-18 15:21) [7]а он его мысленно телепартирует :)
← →
Сергей М. © (2008-01-18 15:23) [8]
> раньше в TClientSocket
А теперь он типа не моден)
← →
Andrewtitoff © (2008-01-18 16:04) [9]2 Сергей М
Ну я тестирую на одном компе, пишу в RemoteHost - LocalHost, а RemotePort такой же как и LocalPort, файл копируется.., если не веришь могу исходник полностью кинуть....
А по поводу не моден ответить нечего, типа того... =))), просто я пишу на 2007 дельфях, боюсь как бы в 2008 - х их уже небыло... =))))
← →
Сергей М. © (2008-01-18 16:50) [10]
> тестирую на одном компе
"на одном компе" <> "через Тырнет"
Запомни как тверди денно и нощно мантру.
> я пишу на 2007 дельфях, боюсь как бы в 2008 - х их уже небыло
Угу.
А то что в 2008 окажутся TTCPClient/Server - это в Библии, наверно, записано)
Еще таз для танкистов - если передающая сторона не скажет принимающей объем следом передаваемых данных, принимающая сторона не будет иметь никаких гарантий корректности размера и содержимого принятых данных.
← →
DVM © (2008-01-18 16:59) [11]
> Andrewtitoff © (18.01.08 16:04) [9]
> Ну я тестирую на одном компе, пишу в RemoteHost - LocalHost,
> а RemotePort такой же как и LocalPort, файл копируется
Советую потестить, например, через GPRS - очень хороший тест надежности копирования.
← →
Andrewtitoff © (2008-01-18 17:51) [12]2 Сергей М
Ну а что толку пытаться тестить в реальных условиях если она как ты говоришь и через тырнет не работает....
Не ну этого конечно тож никто не гарантировал что они в 2008-ой дельфе будут, но по крайне мере раз они их начиная с 7-щй дельфи выставляют на показ а TClientSocket в панели непоказывают хотя они до сих пор и присутствуют - то я считаю что вероятнее всего рано или поздно они на них окончательнно перейдут....
А по поводу объема я и не спорю просто пока тестирую - шлю определенный файл, размер которого мне известен и указываю явным образом его размер так что тут пока что никаких проблем не может быть, но прога то до сих пор толком не работает так что дело не в размере...
Серега если тебе не сложно не мучай меня дурака напиши как это делается,
ес ли ты знаешь как это пишется - то я не думаю что это же займет минут 5 написать простенькую прогу и выложить исходник, я думаю ьебе многие будут благодарны за это!!! =))))
2 DVM ©
Да я понимаю что придется тестить в реальных условиях, тока для этого она дорлжна сначала хотябы так заработать....
← →
Andrewtitoff © (2008-01-18 18:03) [13]2 Сергей М.
Мне нкжен то пример такой жк как
http://delphimaster.net/view/6-1190918176/
тока рабочий и через TcpServer & TcpClient =)))
Заранее благодарен, надеюсь я не очень мнлго прошу... =)))
← →
Сергей М. © (2008-01-19 18:36) [14]
> Мне нкжен то пример
</I
> тока рабочий
>
Предположим, ты его получил.
Что-то ты изменил в нем, пример перестал работать. Что дальше? Опять гундеть-канючить будешь ?)
← →
Andrewtitoff © (2008-01-19 23:39) [15]2 Сергей М.
Да ладно те..., сразу оскорблять.., я конечно не великий программер как ты, но не до такой степени лапух что не смогу переделать под себя элементарный пример...,
Если лень -так и скажи..., а если нет - то кинь пример и забудем, обещаю что больше канючить небуду! =))))
← →
Сергей М. © (2008-01-20 00:18) [16]
> не до такой степени лапух
Ты лапух не "в степени".
Ты просто лАпух.
А "лапухам не до такой степени" не пристало учить и знать Паскаль.
Возражать имеешь ?)
Какие тебе, нахрен, сети и компоненты ?
КАКОГО хрена ты нетипизированным var-параметром передаешь buf ?
Бегом учить паскаль !!
И чтоб тебя здесь не было, пока не выучишь сам язык, прежде чем его применять для даже элементарных задач)
← →
MetalFan © (2008-01-20 02:15) [17]
> [16]
+1
> но не до такой степени лапух что не смогу переделать под
> себя элементарный пример...
так если он для тебя элементарный, то зачем просишь его тебе написать???
← →
Andrewtitoff © (2008-01-20 14:25) [18]2 Сергей М.
Даа.., видиммо для тебя это тоже не такая элементарная задача иначе бы просто прислал бы пеример и не гнул пальцы....
И при чем тут паскаль?, писал я немного в свое время и на паскале, тока писал то что мне надо был, а файли ки мне надо было тока маленткие копировать и т.д. по этому мне хватало read write... и читал - писал себе спокойно по байтам....
И как же ты хочешь что бы я что то изучал - если сам обьяснять не хочешь....
2 MetalFan
Я имел ввиду для него элементарный - видимо ошибся...
← →
Сергей М. © (2008-01-20 19:38) [19]
> иначе бы просто прислал бы пеример
Он тебе не поможет.
Потому что когда тебе говорят про фому, ты все одно гнешь про ерему.
Тебе в [1] был задан вопрос, правильный самостоятельный ответ на который - шаг к самостоятельному решению задачи.
← →
Andrewtitoff © (2008-01-20 20:28) [20]Ну уж это то наверное мне решать поможет он мне или нет...
А по поводу указателей - это да у меня с этим туго..., как то не пользовался в свое время - вот и нехватает знаний... =(((
Но я кстати пробовал писать и Buf^ и @Buf тока от этого ничего не менялось... =)))
Так что если не хочешь помоч - так и скажи, или обьясни как и что делается....
← →
Сергей М. © (2008-01-20 20:31) [21]
> если не хочешь помоч - так и скажи
см. [1]
← →
Сергей М. © (2008-01-20 20:39) [22]
> пробовал писать и Buf^ и @Buf тока от этого ничего не менялось
В данном примере правильным будет Buf^.
А вот почему правильной будет именна такая конструкция - это тебе задание на дом для самостоятельного изучения, это одна из основ языка, без знания которых дальнейшие рассуждения про бессмысленны.
← →
Andrewtitoff © (2008-01-20 20:48) [23]Так почему у меня и с Buf^ все тоже самое как и с Buf, и возвращает тоже 4...
← →
Сергей М. © (2008-01-20 21:00) [24]
> почему у меня и с Buf^ все тоже самое как и с Buf
А какое отношение это имеет к
> возвращает тоже 4
?
Никакого.
Я тебе в [1] задал вопрос, ты до сих пор его игнорируешь. И долго еще эта сказка про белого бычка будет тянуться ?
← →
Andrewtitoff © (2008-01-20 22:00) [25]Да я понял уже давно эту свою ошибку что при описании указателя в статической области памяти будет выделено 4 байт - поэтому и возвращает размер переменной то есть 4 и возвращает....
← →
Сергей М. © (2008-01-20 22:11) [26]Чудесно.
Приводи скорректированный вариант своего кода с учетом этой важной поправки..
← →
Andrewtitoff © (2008-01-21 09:36) [27]2 Сергей М.
Чет я совсем ниче не понимаю..., вот скорректированный код, но все работает как и прежде, вылетает с ошибкой "Canvas does not allow drawing"... =(((
Так в чем ошибка то?, тока не говори про ДНК - это старая шутка... =)))
procedure TMyChat.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
asd:tmemorystream;
len:word;
buf:pointer;
begin
len:=192;
asd:=TMemoryStream.Create;
GetMem(buf,len);
len:= ClientSocket.ReceiveBuf(buf^,len,0);
asd.Position:=0;
asd.WriteBuffer(buf^,len);
asd.SaveToFile("c:\000.txt");
asd.Free;
FreeMem(Buf);
clientsocket.Close;
ShowMessage("clientsocket.Close");
end;
← →
Сергей М. © (2008-01-21 09:49) [28]А где соответствующий скорректированный код сервера ?
И чему равны значения св-ва BlockMode у клиента и у сервера ?
← →
Andrewtitoff © (2008-01-21 10:01) [29]В смысле код сервера?, а я что прислал? (procedure TMyChat.TcpServer1Accept)
значения св-ва BlockMode у клиента и у сервера равны bmBlocking bmThreadBlocking соответственно.
← →
Сергей М. © (2008-01-21 10:32) [30]
> а я что прислал?
А где там коррекция в части ^?
Где там выделение памяти под buf ?
Откуда взялось 192 ?
Где анализ результата вызова ReceiveBuf ?
Где обработчик OnGetThread ?
Где создание доп.потока ?
Почему при bmThreadBlocking работа с клиентом идет в OnAccept, а не как и положено - в доп.потоке, который должен быть создан тобой в OnGetThread ?
Нет этого ничего !
Вот как будет, так и разговор продолжим.
← →
Andrewtitoff © (2008-01-21 10:57) [31]В смысле?
Может я чего то недопонимаю - подскажи тогда дураку...
коррекция в части ^ вот, а где еще чего надо?
len:= ClientSocket.ReceiveBuf(buf^,len,0);
asd.WriteBuffer(buf^,len);
192 - это просто размер пересылаемого мною файла...
А можно поподробнее про анализ результата вызова ReceiveBuf, а то чет я непонимаю чего там как и вообще зачем анализировать?
А что в обработчик OnGetThread писать надо?
И как создавать доп. поток?
Мне нигде ненайти ничего по работе с TcpServer и TcpClient..., нашел примеры тока с Receiveln, SendLn..., там все ясно но там все идет в OnAccept...
Кстати ошибку я вроде нашел.., там просто TcpClient1.Active := True нужно было писать не в прцедуре ConnectClick a уже в SendFileClick...
Теперь прога не вылетает тока почему то обрезает первые 26 байт содержимого файла и добовляет соответственно 26 пробелов в конец... =(((
← →
Andrewtitoff © (2008-01-21 11:11) [32]перенес ве это дело в GetThread, та же история... =(((
procedure TMyChat.TcpServer1GetThread(Sender: TObject;
var ClientSocketThread: TClientSocketThread);
var
s:string;
asd:tmemorystream;
len:word;
buf:pointer;
begin
len:=192;
asd:=TMemoryStream.Create;
GetMem(buf,len);
TcpServer1.ReceiveBuf(buf^,len,0);
asd.Position:=0;
asd.WriteBuffer(buf^,len);
asd.SaveToFile("c:\000.txt");
asd.Free;
FreeMem(Buf);
TcpServer1.Close;
end;
← →
Сергей М. © (2008-01-21 11:15) [33]Ты вообще справку к этим компонентам читать собираешься ?
← →
Andrewtitoff © (2008-01-21 11:24) [34]Так а где ее взять то?, в дельфе написано:
Delphi 2007 for Win32
Using Socket Components
See Also
Collapse AllThe Internet category includes three socket components that allow your network application to form connections to other machines, and that allow you to read and write information over that connection. These are:
TTcpServer
TTcpClient
TUdpSocket
Associated with each of these socket components are socket objects, which represent the endpoint of an actual socket connection. The socket components use the socket objects to encapsulate the socket server calls, so that your application does not need to be concerned with the details of establishing the connection or managing the socket messages.
If you want to customize the details of the connections that the socket components make on your behalf, you can use the properties, events, and methods of the socket objects.
← →
Сергей М. © (2008-01-21 11:25) [35]
> 192 - это просто размер пересылаемого мною файла.
А если файл будет другого размера ? Что, править и перекомпилировать проект будешь ?
> можно поподробнее про анализ результата вызова ReceiveBuf
Справку к этому методу ты проштудировал ? Что тебе там непонятно ?
← →
Сергей М. © (2008-01-21 11:34) [36]У и зачем использовать компоненты, для которых отсутствует справка ?
Не ты ли тут трындел про поддержку компонентов в последующих версиях ?
Отсутствие (частичное или полное) справки к этим компонентам в D2007 должно навести на мысль, что поддержка в будущем этих компонентов под большим вопросом.
← →
Andrewtitoff © (2008-01-21 11:37) [37]Нет, с Receiveln, SendLn я вроде разобрался, покрайне мере пример чата из 7-ых дельфей переделанный мною под TcpServer и TcpClient нормально работает.., буду пересылать размер...
>Справку к этому методу ты проштудировал ? Что тебе там непонятно ?
Так а где ее взять то?, у меня во первых с английским не очень, а во вторых все что есть в справке:
Delphi 2007 VCL Win32 Reference
TCustomWinSocket.ReceiveBuf Method
TCustomWinSocket Class | TCustomWinSocket Members | ScktComp Namespace | Description | See Also
Collapse AllReads up to Count bytes from the socket connection into the Buf parameter.
Pascal
function ReceiveBuf(var Buf; Count: Integer): Integer;
Description
Use ReceiveBuf to read from the socket connection in the OnSocketEvent event handler of a Windows socket object or in the OnRead or OnClientRead event handler of a socket component. ReceiveBuf returns the number of bytes actually read. If no bytes are read, ReceiveBuf returns –1.
ReceiveBuf only works in response to a read notification to a non-blocking windows socket. Blocking sockets must use a TWinSocketStream for reading. The TWinSocketStream object waits for the remote socket to be ready before transferring information.
Note: While the ReceiveLength method can return an estimate of the size of buffer required to retrieve information from the socket, the number of bytes it returns is not necessarily accurate.
← →
Andrewtitoff © (2008-01-21 11:41) [38]Кстати вот так заработало...:
procedure TMyChat.TcpServer1Accept(Sender: TObject;
ClientSocket: TCustomIpClient);
var
s:string;
asd:tmemorystream;
len:word;
buf:pointer;
begin
len:=192;
asd:=TMemoryStream.Create;
GetMem(buf,len);
ClientSocket.ReceiveBuf(buf^,len,0);
asd.Position:=0;
asd.WriteBuffer(buf^,len);
asd.SaveToFile("c:\000.txt");
asd.Free;
FreeMem(Buf);
TcpServer1.Close;
end;
← →
Сергей М. © (2008-01-21 11:50) [39]
> Кстати вот так заработало
Теперь разнеси своего клиента и сервера по разным углам Тырнета и попытайся передать файл размером более 8 кб. Или попытайся обслужить более чем одного клиента одновременно. Грабли тебе гарантированы.
> у меня во первых с английским не очень
Печально. Ничего путного у тебя не получится, пока не выучишь.
> все что есть в справке
Это говорит как раз о том, что Борланд прекратил поддержку этих компонентов.
Продолжай зарабатывать себе геморрой.
← →
Andrewtitoff © (2008-01-21 12:40) [40]>Теперь разнеси своего клиента и сервера по разным углам Тырнета и попытайся передать файл размером более 8 кб
Вот блин точно..., Len в ReceiveBuf(buf^,len,0); имеет тип word, а он равен 2 байтам т.е. от 0 до 65535... =((( , а что что бы послать файл побольше его нужно разбивать, или есть какой нить способ?
>Или попытайся обслужить более чем одного клиента одновременно
А как сделать то??, хотя для задачи которая на данный момент передомной стоит мне вполне хватит две пары клиент-сервер, но все таки хотелось бы знать и как сделать с несколькими клиентами... =(((
Страницы: 1 2 вся ветка
Форум: "Сети";
Текущий архив: 2009.03.29;
Скачать: [xml.tar.bz2];
Память: 0.57 MB
Время: 0.389 c